package jehc.djshi.workflow.util;

import cn.hutool.core.collection.CollectionUtil;
import jehc.djshi.common.base.BaseResult;
import jehc.djshi.common.base.BaseService;
import jehc.djshi.common.util.ExceptionUtil;
import jehc.djshi.common.util.ImageAnd64Binary;
import jehc.djshi.common.util.StringUtil;
import jehc.djshi.workflow.model.LcNodeAttribute;
import jehc.djshi.workflow.model.LcNodeCandidate;
import jehc.djshi.workflow.param.LcReceiveNParam;
import jehc.djshi.workflow.param.LcReceiveParam;
import jehc.djshi.workflow.param.LcTaskParam;
import jehc.djshi.workflow.service.ActRunVariableService;
import jehc.djshi.workflow.vo.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.*;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.*;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.TaskListener;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.delegate.event.impl.ActivitiEventBuilder;
import org.activiti.engine.form.FormProperty;
import org.activiti.engine.form.StartFormData;
import org.activiti.engine.form.TaskFormData;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricActivityInstanceQuery;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.RuntimeServiceImpl;
import org.activiti.engine.impl.ServiceImpl;
import org.activiti.engine.impl.bpmn.behavior.*;
import org.activiti.engine.impl.cfg.IdGenerator;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.interceptor.CommandExecutor;
import org.activiti.engine.impl.javax.el.ExpressionFactory;
import org.activiti.engine.impl.javax.el.ValueExpression;
import org.activiti.engine.impl.juel.ExpressionFactoryImpl;
import org.activiti.engine.impl.juel.SimpleContext;
import org.activiti.engine.impl.persistence.entity.*;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.activiti.engine.impl.pvm.runtime.AtomicOperation;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.DelegationState;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.zip.ZipInputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.impl.pvm.PvmException;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
import org.activiti.engine.impl.pvm.runtime.InterpretableExecution;

/**
 * @Desc activiti核心引擎
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Component
@Slf4j
@Data
public class ActivitiUtil extends BaseService {
	public static final String ACT_CODE_10 = "10";
	public static final String ACT_CODE_20 = "20";
	public static final String ACT_CODE_30 = "30";
	public static final String ACT_CODE_40 = "40";
	public static final String USER_TASK = "userTask";//用户节点
	public static final String END = "END";//结束节点
	public static final String PARALLELGATEWAY= "parallelGateway";//并行网关
	public static final String START="START";//开始节点
	public static final String STARTEVENT= "startEvent";
	public static final String EXCLUSIVEGATEWAY= "exclusiveGateway";
	public static final String BEHAVIOR_0 = "0";//0提交
	public static final String BEHAVIOR_10 = "10";//10通过
	public static final String BEHAVIOR_20 = "20";//20驳回
	public static final String BEHAVIOR_30 = "30";//30弃权
	public static final String BEHAVIOR_40 = "40";//40撤回
	public static final String BEHAVIOR_50 = "50";//50强行终止（终止流程）
	public static final String BEHAVIOR_60 = "60";//60执行跳转
	public static final String BEHAVIOR_70 = "70";//70转办
	public static final String BEHAVIOR_80 = "80";//80委派
	public static final String BEHAVIOR_90 = "90";//90加签
	public static final String BEHAVIOR_100 = "100";//100催办
	public static final String BEHAVIOR_110 = "110";//110设置任务归属人
	public static final String BEHAVIOR_120 = "120";//120挂起流程
	public static final String BEHAVIOR_130 = "130";//130激活流程

	@Autowired
	private IdentityService identityService;
	@Autowired
	private RuntimeService runtimeService;
	@Autowired
	private HistoryService historyService;
	@Autowired
	private TaskService taskService;
	@Autowired
	private ManagementService managementService;
	@Autowired
	private FormService formService;
	@Autowired
	private RepositoryService repositoryService;
	@Autowired
	ActRunVariableService actRunVariableService;

	/**
	 *
	 * @param bpmn
	 * @return
	 */
	public Deployment createDeployment(String name,String bpmn){
		Deployment deployment=null;
		if(!StringUtil.isEmpty(bpmn)){
			deployment = repositoryService.createDeployment().name(name).addString(name+".bpmn",bpmn).deploy();
			log.info("流程部署成功，信息如下:"+"ID---"+deployment.getId()+"----name---"+deployment.getName()+"----time----"+deployment.getDeploymentTime());
		}else{
			log.info("部署流程失败");
		}
		return deployment;
	}

	/**
	 * 部署流程
	 * @param file 部署的文件流
	 * @return 返回流程部署对象
	 */
	public Deployment createDeployment(File file){
		Deployment deployment=null;
		if(FilenameUtils.getExtension(file.getName()).equals("zip")|| FilenameUtils.getExtension(file.getName()).equals("bar")){
			ZipInputStream zipInputStream;
			try {
				zipInputStream = new ZipInputStream(new FileInputStream(file));
				deployment = repositoryService.createDeployment().addZipInputStream(zipInputStream).deploy();
				log.info("流程部署成功，信息如下:"+"ID---"+deployment.getId()+"----name---"+deployment.getName()+"----time----"+deployment.getDeploymentTime());
			} catch (FileNotFoundException e) {
				log.error("流程部署失败,原因所部署的文件解压失败");
				throw new ExceptionUtil(e.getMessage(),e.getCause());
			}
		}else{
			log.info("流程部署失败,原因所部署的文件类型不正确");
		}
		return deployment;
	}
	
	/**
	 * 删除流程部署
	 * @param deploymentId 流程部署Id号
	 */
	public boolean deleteDeploymentById(String deploymentId){
		boolean b=true;
		try {
			repositoryService.deleteDeployment(deploymentId,true);
		} catch (Exception e) {
			b =false;
			log.error("删除流程部署异常：{}",e);
		}
		return b;
	}
	
	/**
	 * 根据流程定义的key启动工作流实例
	 * 发起一个流程实例
	 * @param key 流程部署
	 * @param businessKey 业务键
	 * @param variables 参数
	 * @return
	 */
	public ProcessInstance startProcessInstanceByKey(String key,String businessKey,Map<String, Object> variables) {
		try {
			ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key, businessKey, variables);
			return processInstance;
		} catch (Exception e) {
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}
	
	/**
	 * 设置跨节点提交
	 * 根据流程定义的key启动工作流实例
	 * 发起一个流程实例
	 * @param key 流程部署
	 * @param businessKey 业务键
	 * @param initialActivityId [设置跨节点提交]
	 * @param variables 参数
	 * @return
	 */
	public ProcessInstance startProcessInstanceByKey(String key,String businessKey,String initialActivityId,Map<String, Object> variables) {
		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key, businessKey, variables);
		return processInstance;
	} 


	/**
	 * 根据流程实例查找高亮流程图（原生态）
	 * @param processInstanceId 流程实例id
	 * @return
	 */
	public InputStream getHightDiagram(String processInstanceId) {
		//获得流程实例
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
				.processInstanceId(processInstanceId).singleResult();
		String processDefinitionId = StringUtils.EMPTY;
		if (processInstance == null) {
			//查询已经结束的流程实例
			HistoricProcessInstance processInstanceHistory = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
			if (processInstanceHistory == null)
				return null;
			else
				processDefinitionId = processInstanceHistory.getProcessDefinitionId();
		} else {
			processDefinitionId = processInstance.getProcessDefinitionId();
		}

		//使用宋体
		String fontName = "宋体";
		//获取BPMN模型对象
		BpmnModel model = repositoryService.getBpmnModel(processDefinitionId);
		//获取流程实例当前的节点，需要高亮显示
		List<String> currentActs = Collections.EMPTY_LIST;
		if (processInstance != null)
			currentActs = runtimeService.getActiveActivityIds(processInstance.getId());
		ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
		return processEngine.getProcessEngineConfiguration()
				.getProcessDiagramGenerator()
				.generateDiagram(model, "png", currentActs, new ArrayList<String>(), fontName, fontName, fontName, null, 1.0);
	}
	
	/**
	 * 根据流程实例Id查找流程图（原生态）
	 * @param processInstanceId 流程实例id
	 */
	public void getProcessInstanceImageById(String processInstanceId,HttpServletResponse response){
		InputStream resourceAsStream = null;
		try {
			//根据流程实例id查询流程实例
			ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
			//根据流程定义id查询流程定义
			ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processInstance.getProcessDefinitionId()).singleResult();
			String resourceName=processDefinition.getDiagramResourceName();
			//打开流程资源流
			resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);
			runtimeService.getActiveActivityIds(processInstance.getId());
			//输出到浏览器
			byte[] byteArray = IOUtils.toByteArray(resourceAsStream);
			ServletOutputStream servletOutputStream = response.getOutputStream();
			servletOutputStream.write(byteArray, 0, byteArray.length);
			servletOutputStream.flush();
			servletOutputStream.close();
		} catch (Exception ex) {
			log.error("根据流程实例查找流程图异常：{}",ex);
			throw new ExceptionUtil(ex.getMessage(),ex.getCause());
		}
	}
	
	
	/**
	 * 查找流程图信息
	 * @param executionId
	 * @param processInstanceId
	 * @return
	 */
	public Map<String,Object> getActivityImageInfo(String executionId,String processInstanceId){
		//根据executionId查询当前执行的节点
		ExecutionEntity execution=(ExecutionEntity) runtimeService.createExecutionQuery().processInstanceId(processInstanceId).executionId(executionId).singleResult();
		//获取当前节点的activityId
		String activityId=execution.getActivityId();
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl)repositoryService).getDeployedProcessDefinition(processInstance.getProcessDefinitionId());
		List<ActivityImpl> activities = processDefinitionEntity.getActivities();
		Map<String,Object> activityImageInfo=new HashMap<String,Object>();
		for (ActivityImpl activityImpl : activities) {
			String id=activityImpl.getId();
			//判断是否是当前节点
			if(id.equals(activityId)){
				activityImageInfo.put("x", activityImpl.getX());
				activityImageInfo.put("y", activityImpl.getY());
				activityImageInfo.put("width", activityImpl.getWidth());
				activityImageInfo.put("height", activityImpl.getHeight());
				break;//跳出循环
			}
		}
		return activityImageInfo;
	}

	/**
	 * 根据流程部署id查找流程定义对象
	 * @param deploymentId 流程部署id
	 * @return
	 */
	public ProcessDefinition getProcessDefinition(String deploymentId){
		try {
			ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
			return processDefinition;
		} catch (Exception e) {
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}

	/**
	 * 根据流程定义id查询流程定义
	 * @return
	 */
	public ProcessDefinition getProcessDefinitionByDid(String processDefinitionId){
		ProcessDefinition processDefinition=null;
		try {
			processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
		} catch (Exception e) {
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
		return processDefinition;
	}

	/**
	 * 根据taskId 获取当前活动的任务
	 * @param taskId
	 * @return
	 */
	public HistoricTaskInstance getTaskById(String taskId){
		//根据taskId 获取当前活动任务
		HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();//根据对象获取流程定义Id
		return historicTaskInstance;
	}

	/**
	 * 根据taskId查询当前活动的任务
	 * @param taskId
	 * @return
	 */
	public Task getRunTaskById(String taskId){
		if(StringUtil.isEmpty(taskId)){
			log.warn("查询当前运行任务对象时，未能获取到任务id",taskId);
			throw new ExceptionUtil("查询当前运行任务对象时，未能获取到任务id");
		}
		//根据taskId 获取当前活动任务
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();//根据对象获取流程定义Id
		return task;
	}

	/**
	 * 根据流程实例Id查找流程对象
	 * @param processInstanceId 流程实例Id
	 * @return
	 */
	public ProcessInstance getProcessInstanceById(String processInstanceId){
		ProcessInstance processInstance=null;
		try {
			processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		} catch (Exception e) {
			log.error("查找流程实例对象异常：{}",e);
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
		return processInstance;
	}

	/**
	 * 获取所有流程定义集合
	 * @return
	 */
	public List<ProcessDefinition> getProcessDefinitionList(){
		return repositoryService.createProcessDefinitionQuery().list();
	}

	/**
	 * 根据任务Id获取activityId,businessKey[业务Key],variables[节点变量]
	 * @param taskId
	 * @return
	 */
	public Map<String, Object> getTask(String taskId){
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		ExecutionEntity executionEntity=(ExecutionEntity) runtimeService.createExecutionQuery().executionId(task.getExecutionId()).processInstanceId(task.getProcessInstanceId()).singleResult();
		//获取当前正在执行的节点
		String activityId = executionEntity.getActivityId();
		String processInstanceId = task.getProcessInstanceId();
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		//业务Key即可以作为业务ID处理
		String businessKey = processInstance.getBusinessKey();
		//获取节点变量
		Map<String, Object> variables = taskService.getVariables(taskId);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("taskVariables", variables);
		map.put("businessKey", businessKey);
		map.put("activityId", activityId);
		map.put("task", task);
		return map;
	}


	/**
	 * 根据TaskId查找Task对象
	 * @param taskId
	 * @return
	 */
	public Task getTaskByTaskId(String taskId){
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		return task;
	}


	/**
	 * 查找指定人分配出去的任务集合
	 * @param userId
	 * @return
	 */
	public List changeOwnerTaskList(String userId){
		if(StringUtil.isEmpty(userId)){
			return new ArrayList();
		}
		List<Task>list = taskService.createTaskQuery().taskOwner(userId).orderByTaskCreateTime().desc().list();
		return list;
	}

	/**
	 * 查找指定人分配出去的任务集合并分页
	 * @param condition
	 * @return
	 */
	public Map<String,Object> changeOwnerTaskList(Map<String,Object> condition){
		if(CollectionUtil.isEmpty(condition)){
			return new HashMap<>();
		}
		if(null == condition.get("userId")){
			return new HashMap<>();
		}
		Map<String, Object> map = new HashMap<String, Object>();
		int start = new Integer(condition.get("start").toString());
		int pageSize = new Integer(condition.get("pageSize").toString());
		Object taskName =  condition.get("taskName");
		TaskQuery taskQuery = taskService.createTaskQuery();
		if(null != taskName){
			taskQuery.taskNameLike(String.valueOf(taskName));
		}
		List<Task> list = taskQuery.taskOwner(condition.get("userId")+"").orderByTaskCreateTime().desc().listPage(start, pageSize);
		long count = taskQuery.count();
		map.put("TaskList", list);
		map.put("TaskCount", count);
		return map;
	}

	/**
	 * 根据条件查询任务
	 * @param lcTaskParam
	 * @return
	 */
	public List<Task> getTaskList(LcTaskParam lcTaskParam){
		if(null == lcTaskParam){
			return new ArrayList<>();
		}
		TaskQuery taskQuery = taskService.createTaskQuery();
		if(null != lcTaskParam.getTaskName()){
			taskQuery.taskNameLike(String.valueOf(lcTaskParam.getTaskName()));
		}
		if(null != lcTaskParam.getBusinessKey()){
			taskQuery.processInstanceBusinessKey(lcTaskParam.getBusinessKey());
		}
		if(null != lcTaskParam.getTransactors()){
			taskQuery.taskAssignee(lcTaskParam.getTransactors());
		}
		if(null != lcTaskParam.getGroup()){
			taskQuery.taskCandidateGroup(lcTaskParam.getGroup());
		}
		if(null != lcTaskParam.getOwner()){
			taskQuery.taskOwner(lcTaskParam.getOwner());
		}
		if(null != lcTaskParam.getCandidates()){
			taskQuery.taskCandidateUser(lcTaskParam.getCandidates());
		}
		List<Task> list = taskQuery.orderByTaskCreateTime().desc().list();
		return list;
	}

	/**
	 * 根据指定人+流程示例id查找分配出去的任务集合 并分页
	 * @param condition
	 * @return
	 */
	public Map<String,Object> changeOwnerTaskListByInstanceId(Map<String,Object> condition){
		if(CollectionUtil.isEmpty(condition)){
			return new HashMap<>();
		}
		if(null == condition.get("userId")){
			return new HashMap<>();
		}
		if(null == condition.get("instanceId")){
			return new HashMap<>();
		}
		Map<String, Object> map = new HashMap<String, Object>();
		int start = new Integer(condition.get("start").toString());
		int pageSize = new Integer(condition.get("pageSize").toString());
		String instanceId = ""+condition.get("instanceId");
		List<Task> list = taskService.createTaskQuery().taskOwner(condition.get("userId")+"").orderByTaskCreateTime().desc().processInstanceId(instanceId).listPage(start, pageSize);
		long count = taskService.createTaskQuery().count();
		map.put("TaskList", list);
		map.put("TaskCount", count);
		return map;
	}

	/**
	 * 完成任务
	 * @param taskId
	 * @param map
	 * @return
	 */
	public boolean completeTask(String taskId,Map<String,Object> map){
		try {
			Task task = getTaskByTaskId(taskId);
			if(null == task){
				throw new ExceptionUtil("未能找到任务："+taskId);
			}
			if (DelegationState.PENDING == task.getDelegationState()) {//如果是委派任务则调用resolveTask
				resolveTask(taskId,map);//建议map传递值之后 可以将归属人设置为回到节点处理人
				taskService.complete(taskId,map);
			}else{
				taskService.complete(taskId,map);//普通任务
			}
			return true;
		} catch (Exception e) {
			log.error("完成任务异常：{}",e);
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}

	/**
	 * 完成委派任务
	 * @param taskId
	 * @param map
	 * @return
	 */
	public boolean resolveTask(String taskId,Map<String,Object> map){
		try {
			taskService.resolveTask(taskId,map);
			return true;
		} catch (Exception e) {
			log.error("完成任务委派异常：{}",e);
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}

	
	/**
	 * 根据用户Id+taskId签收任务
	 * @param taskId
	 * @param userId 用户id
	 * @return 0失败---1成功
	 */
	public boolean claimTask(String taskId,String userId){
		boolean b = true;
		try {
			taskService.claim(taskId, userId);
		} catch (Exception e) {
			log.error("签收任务异常：{}",e);
			b = false;
		}
		return b;
	}
	
	/**
	 * 判断流程实例是否结束
	 * @param processInstanceId
	 * @return
	 */
	public boolean validatePEnd(String processInstanceId){
		ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		if(pi==null){
			return true;
		}else{
			return false;
		}
	}
	
	/**
	 * 挂起流程实例（可作为撤销流程）
	 * @param processInstanceId
	 * @return
	 */
	public boolean suspendProcessInstanceById(String processInstanceId){
		try {
			runtimeService.suspendProcessInstanceById(processInstanceId);
		} catch (Exception e) {
			log.error("挂起流程实例异常：{}",e);
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
		return true;
	}
	
	/**
	 * 激活流程实例(开启流程实例)
	 * @param processInstanceId
	 * @return
	 */
	public boolean activateProcessInstanceById(String processInstanceId){
		try {
			runtimeService.activateProcessInstanceById(processInstanceId);
		} catch (Exception e) {
			log.error("激活流程实例异常：{}",e);
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
		return true;
	}
	
	/**
	 * 删除流程部署
	 * @param deploymentId 流程部署Id
	 * @return
	 * @throws Exception
	 * 说明：因为删除的是流程定义，而流程定义的部署是属于仓库服务的，所以应该先得到RepositoryService
		    如果该流程定义下没有正在运行的流程，则可以用普通删除。
		    如果是有关联的信息，用级联删除。一般情况下用普通删除就可以。
		    由于级联删除涉及的数据比较多，一般只开放给超级管理员使用。
	 */
	public boolean delDeployment(String deploymentId){
		try {
		  //普通删除，如果当前规则下有正在执行的流程，则抛异常
		  repositoryService.deleteDeployment(deploymentId);
		  //级联删除,会删除和当前规则相关的所有信息，包括历史
		  repositoryService.deleteDeployment(deploymentId, true);
		  return true;
		} catch (Exception e) {
			log.error("删除流程部署异常：{}",e);
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}

	
	/**
	 * 根据任务Id获取ActivityImpl
	 * @param taskId 任务Id
	 * @return
	 */
	public ActivityImpl getActivityImpl(String taskId){
		ActivityImpl activityImpl = null;
		//获取当前活动节点ID  
        TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task != null) {  
        	//取得流程定义  
            ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(task.getProcessDefinitionId());  
            if (processDefinition != null) {  
            	String activityId = task.getTaskDefinitionKey();   
                //根据流程定义，获取该流程实例的结束节点  
                if (activityId.toUpperCase().equals(ActivitiUtil.END)) {
                    for (ActivityImpl actImpl : processDefinition.getActivities()) {  
                        List<PvmTransition> pvmTransitionList = actImpl.getOutgoingTransitions();  
                        if (pvmTransitionList.isEmpty()) {  
                            return actImpl;  
                        }  
                    }  
                }  
                // 根据节点ID，获取对应的活动节点  
                activityImpl = ((ProcessDefinitionImpl) processDefinition).findActivity(activityId);  
            }  
        }  
        return activityImpl;  
	}

	/**
	 * 根据任务Id查找下一步节点集合
	 * @param taskId 任务Id
	 * @param conditionMap 传入节点上变量 目的让其能自动找到合规的目标节点
	 * @return
	 */
	public List<TaskDefinition> getNextTaskDefinitionList(String taskId,Map<String, Object> conditionMap){
		ActivityImpl activityImpl = null;
		NodeEntity nodeEntity = new NodeEntity();
		//查询当前活动节点id
        TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(taskId).singleResult();
        String activityId = "";
        if (task != null) {  
        	//取得流程定义  
            ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(task.getProcessDefinitionId());  
            if (processDefinition != null) {  
            	activityId = task.getTaskDefinitionKey();   
                //根据流程定义，获取该流程实例的结束节点  
                if (activityId.toUpperCase().equals(ActivitiUtil.END)) {
                    for (ActivityImpl actImpl : processDefinition.getActivities()) {  
                        List<PvmTransition> pvmTransitionList = actImpl.getOutgoingTransitions();  
                        if (pvmTransitionList.isEmpty()) {  
                        	activityImpl = actImpl;  
                            break;
                        }  
                    }  
                }else{
                	 //根据节点ID，获取对应的活动节点  
                    activityImpl = ((ProcessDefinitionImpl) processDefinition).findActivity(activityId);  
                }
            }  
        }  
        if(null != activityImpl){
        	return nextTaskDefinition(activityImpl, activityId, conditionMap,nodeEntity);
        }else{
        	return null;
        }
	}

	/**
	 * 下一个任务节点信息,
	 * 如果下一个节点为用户任务则直接返回,
	 * 如果下一个节点为排他网关, 获取排他网关Id信息, 根据排他网关Id信息和execution获取流程实例排他网关Id为key的变量值,
	 * 根据变量值分别执行排他网关后线路中的el表达式, 并找到el表达式通过的线路后的用户任务
	 * @param activityImpl 流程节点信息
	 * @param activityId 当前流程节点Id信息
	 * @param conditionMap 排他网关顺序流线段判断条件（或自定义变量）
	 * @return
	 */
	private List<TaskDefinition> nextTaskDefinition(ActivityImpl activityImpl, String activityId, Map<String, Object> conditionMap,NodeEntity nodeEntity){
		if(null == nodeEntity){
			nodeEntity = new NodeEntity();
		}

		PvmActivity ac = null;
		Object conditionTextEl = null;
		// 如果遍历节点为用户任务并且节点不是当前节点信息
		if (ActivitiUtil.USER_TASK.equals(activityImpl.getProperty("type")) && !activityId.equals(activityImpl.getId())) {
			try {
				// 获取该节点下一个节点信息
				TaskDefinition taskDefinition = null;
				if(((ActivityImpl) activityImpl).getActivityBehavior() instanceof UserTaskActivityBehavior){
					taskDefinition = ((UserTaskActivityBehavior) ((ActivityImpl) activityImpl).getActivityBehavior()).getTaskDefinition();
					nodeEntity.getTaskDefinitions().add(taskDefinition);
				}else if(((ActivityImpl) activityImpl).getActivityBehavior() instanceof SequentialMultiInstanceBehavior){//会签多实例串行
					SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior = ((SequentialMultiInstanceBehavior) ((ActivityImpl) activityImpl).getActivityBehavior());
					taskDefinition = ((UserTaskActivityBehavior)sequentialMultiInstanceBehavior.getInnerActivityBehavior()).getTaskDefinition();
					nodeEntity.getTaskDefinitions().add(taskDefinition);
				}else if(((ActivityImpl) activityImpl).getActivityBehavior() instanceof ParallelMultiInstanceBehavior){//会签多实例并行
					ParallelMultiInstanceBehavior parallelMultiInstanceBehavior =  ((ParallelMultiInstanceBehavior) ((ActivityImpl) activityImpl).getActivityBehavior());
					taskDefinition = ((UserTaskActivityBehavior)parallelMultiInstanceBehavior.getInnerActivityBehavior()).getTaskDefinition();
					nodeEntity.getTaskDefinitions().add(taskDefinition);
				}else if(((ActivityImpl) activityImpl).getActivityBehavior() instanceof MultiInstanceActivityBehavior){
					MultiInstanceActivityBehavior multiInstanceActivityBehavior =  ((MultiInstanceActivityBehavior) ((ActivityImpl) activityImpl).getActivityBehavior());
					taskDefinition = ((UserTaskActivityBehavior)multiInstanceActivityBehavior.getInnerActivityBehavior()).getTaskDefinition();
					nodeEntity.getTaskDefinitions().add(taskDefinition);
				}
			}catch (Exception e){
				log.error("获取下一个任务节点TaskDefinition异常：{}",e);
			}
			return nodeEntity.getTaskDefinitions();//必须return 不在继续查找
		} else if(ActivitiUtil.EXCLUSIVEGATEWAY.equals(activityImpl.getProperty("type"))){// 当前节点为exclusiveGateway 则查找排他网关下的节点集合
			List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();
			if(!CollectionUtil.isEmpty(outTransitions)){ // 如果排他网关有多条线路信息 则递归查找直到查找到节点位置（如该网关节点后面继续放网关 则需要继续找）
				for (PvmTransition tr1 : outTransitions) {
					conditionTextEl = tr1.getProperty("conditionText"); // 获取排他网关线路判断条件信息（即设计器中设计的表达式模板）
					if(null == conditionTextEl){
						log.warn("下一步连线节点未配置流程条件表达式，无法定位到连线对应的节点，连线名称：{},连线定义编号：{}，外层网关名称：{}，外层网关编号：{}",tr1.getProperty("name"),tr1.getId(),activityImpl.getProperty("name"),activityImpl.getId());
						continue;
					}
					if (isCondition(StringUtils.trim(conditionTextEl.toString()), conditionMap)) {// 判断el表达式是否成立
						nextTaskDefinition((ActivityImpl) tr1.getDestination(), activityId, conditionMap,nodeEntity);
					}
				}
			}
//			if (outTransitions.size() == 1) {// 如果排他网关只有一条线路信息 则递归查找直到查找到节点位置（如该网关节点后面继续放网关 则需要继续找）
//				return nextTaskDefinition((ActivityImpl) outTransitions.get(0).getDestination(), activityId, conditionMap,nodeEntity);
//			} else if (outTransitions.size() > 1) { // 如果排他网关有多条线路信息 则递归查找直到查找到节点位置（如该网关节点后面继续放网关 则需要继续找）
//				for (PvmTransition tr1 : outTransitions) {
//					conditionTextEl = tr1.getProperty("conditionText"); // 获取排他网关线路判断条件信息（即设计器中设计的表达式模板）
//					if(null == conditionTextEl){
//						log.warn("下一步连线节点未配置流程条件表达式，无法定位到连线对应的节点，连线名称：{},连线定义编号：{}，外层网关名称：{}，外层网关编号：{}",tr1.getProperty("name"),tr1.getId(),activityImpl.getProperty("name"),activityImpl.getId());
//						continue;
//					}
//					if (isCondition(StringUtils.trim(conditionTextEl.toString()), conditionMap)) {// 判断el表达式是否成立
//						nextTaskDefinition((ActivityImpl) tr1.getDestination(), activityId, conditionMap,nodeEntity);
//					}
//				}
//			}
		}else if(ActivitiUtil.PARALLELGATEWAY.equals(activityImpl.getProperty("type"))){//并行网关
			List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();
			if(!CollectionUtil.isEmpty(outTransitions)){
				for (PvmTransition tr1 : outTransitions) {//并行网关无需条件
					nextTaskDefinition((ActivityImpl) tr1.getDestination(), activityId, conditionMap,nodeEntity);// 如果并行网关有多条线路信息 则递归查找直到查找到节点位置（如该网关节点后面继续放网关 则需要继续找）
				}
			}
//			if (outTransitions.size() == 1) {// 如果并行网关只有一条线路信息 则递归查找直到查找到节点位置（如该网关节点后面继续放网关 则需要继续找）
//				return nextTaskDefinition((ActivityImpl) outTransitions.get(0).getDestination(), activityId, conditionMap,nodeEntity);
//			} else if (outTransitions.size() > 1) { // 如果并行网关有多条线路信息 则递归查找直到查找到节点位置（如该网关节点后面继续放网关 则需要继续找）
//				for (PvmTransition tr1 : outTransitions) {//并行网关无需条件
//					nextTaskDefinition((ActivityImpl) tr1.getDestination(), activityId, conditionMap,nodeEntity);
//				}
//			}
		}else {//除此之外查询节点所有流向线路信息
			List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();
			List<PvmTransition> outTransitionsTemp = null;
			for (PvmTransition tr : outTransitions) {
				ac = tr.getDestination(); //获取线路的终点节点
				if (ActivitiUtil.EXCLUSIVEGATEWAY.equals(ac.getProperty("type"))) {// 如果流向线路为排他网关 则查找排他网关下的节点集合
					outTransitionsTemp = ac.getOutgoingTransitions();
					if(CollectionUtil.isEmpty(outTransitionsTemp)){//则递归查找直到查找到节点位置（如该网关节点后面继续放网关 则需要继续找）
						for (PvmTransition tr1 : outTransitionsTemp) {
							conditionTextEl = tr1.getProperty("conditionText"); // 获取排他网关线路判断条件信息
							if(null == conditionTextEl){
								log.warn("下一步连线节点未配置流程条件表达式，无法定位到连线对应的节点，连线名称：{},连线定义编号：{}，外层网关名称：{}，外层网关编号：{}",tr1.getProperty("name"),tr1.getId(),ac.getProperty("name"),ac.getId());
								continue;
							}
							if (isCondition(StringUtils.trim(conditionTextEl.toString()), conditionMap)) {	// 判断el表达式是否成立
								nextTaskDefinition((ActivityImpl) tr1.getDestination(), activityId, conditionMap,nodeEntity);
//								return taskDefinitions;
							}
						}
					}
//					if (outTransitionsTemp.size() == 1) {// 如果排他网关只有一条线路信息  则递归查找直到查找到节点位置（如该网关节点后面继续放网关 则需要继续找）
//						return nextTaskDefinition((ActivityImpl) outTransitionsTemp.get(0).getDestination(), activityId, conditionMap,nodeEntity);
//					} else if (outTransitionsTemp.size() > 1) { // 如果排他网关有多条线路信息  则递归查找直到查找到节点位置（如该网关节点后面继续放网关 则需要继续找）
//						for (PvmTransition tr1 : outTransitionsTemp) {
//							conditionTextEl = tr1.getProperty("conditionText"); // 获取排他网关线路判断条件信息
//							if(null == conditionTextEl){
//								log.warn("下一步连线节点未配置流程条件表达式，无法定位到连线对应的节点，连线名称：{},连线定义编号：{}，外层网关名称：{}，外层网关编号：{}",tr1.getProperty("name"),tr1.getId(),ac.getProperty("name"),ac.getId());
//								continue;
//							}
//							if (isCondition(StringUtils.trim(conditionTextEl.toString()), conditionMap)) {	// 判断el表达式是否成立
//								nextTaskDefinition((ActivityImpl) tr1.getDestination(), activityId, conditionMap,nodeEntity);
////								return taskDefinitions;
//							}
//						}
//					}
				} else if (ActivitiUtil.USER_TASK.equals(ac.getProperty("type")) && !activityId.equals(ac.getId())) {//任务
					try {
						if(((ActivityImpl) ac).getActivityBehavior() instanceof UserTaskActivityBehavior){
							TaskDefinition taskDefinition = ((UserTaskActivityBehavior) ((ActivityImpl) ac).getActivityBehavior()).getTaskDefinition();
							nodeEntity.getTaskDefinitions().add(taskDefinition);
						}else if(((ActivityImpl) ac).getActivityBehavior() instanceof SequentialMultiInstanceBehavior){//会签多实例串行
							SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior = ((SequentialMultiInstanceBehavior) ((ActivityImpl) ac).getActivityBehavior());
							TaskDefinition taskDefinition = ((UserTaskActivityBehavior)sequentialMultiInstanceBehavior.getInnerActivityBehavior()).getTaskDefinition();
							nodeEntity.getTaskDefinitions().add(taskDefinition);
						}else if(((ActivityImpl) ac).getActivityBehavior() instanceof ParallelMultiInstanceBehavior){//会签多实例并行
							ParallelMultiInstanceBehavior parallelMultiInstanceBehavior =  ((ParallelMultiInstanceBehavior) ((ActivityImpl) ac).getActivityBehavior());
							TaskDefinition taskDefinition = ((UserTaskActivityBehavior)parallelMultiInstanceBehavior.getInnerActivityBehavior()).getTaskDefinition();
							nodeEntity.getTaskDefinitions().add(taskDefinition);
						}else if(((ActivityImpl) ac).getActivityBehavior() instanceof MultiInstanceActivityBehavior){
							MultiInstanceActivityBehavior multiInstanceActivityBehavior =  ((MultiInstanceActivityBehavior) ((ActivityImpl) ac).getActivityBehavior());
							TaskDefinition taskDefinition = ((UserTaskActivityBehavior)multiInstanceActivityBehavior.getInnerActivityBehavior()).getTaskDefinition();
							nodeEntity.getTaskDefinitions().add(taskDefinition);
						}
					}catch (Exception e){
						log.error("获取下一个任务节点TaskDefinition异常：{}",e);
					}

//					return taskDefinitions;
				}else if(ActivitiUtil.PARALLELGATEWAY.equals(ac.getProperty("type"))) {//并行网关
					outTransitionsTemp = ac.getOutgoingTransitions();
					if(!CollectionUtil.isEmpty(outTransitionsTemp)){
						for (PvmTransition tr1 : outTransitionsTemp) {//并行网关无需条件
							nextTaskDefinition((ActivityImpl) tr1.getDestination(), activityId, conditionMap,nodeEntity);// 如果并行网关有多条线路信息 则递归查找直到查找到节点位置（如该网关节点后面继续放网关 则需要继续找）
						}
					}
//					if (outTransitionsTemp.size() == 1) {// 如果排他网关只有一条线路信息  则递归查找直到查找到节点位置（如该网关节点后面继续放网关 则需要继续找）
//						return nextTaskDefinition((ActivityImpl) outTransitionsTemp.get(0).getDestination(), activityId, conditionMap,nodeEntity);
//					} else if (outTransitionsTemp.size() > 1) { // 如果排他网关有多条线路信息  则递归查找直到查找到节点位置（如该网关节点后面继续放网关 则需要继续找）
//						for (PvmTransition tr1 : outTransitionsTemp) {
//							nextTaskDefinition((ActivityImpl) tr1.getDestination(), activityId, conditionMap,nodeEntity);
//						}
//					}
				} else {//其它类型无需获取
					log.info("其它类型无需获取：",activityImpl.toString());
				}
			}
//			return taskDefinitions;
		}
		return nodeEntity.getTaskDefinitions();
	}

	/**
	 * 根据key和value判断el表达式是否通过信息
	 * @param el el表达式信息
	 * @param conditionMap el表达式传入值信息 （Map conditionMap = new HashMap();conditionMap.put("condition1001", true);）
	 * @return
	 */
	private boolean isCondition(String el, Map<String, Object> conditionMap) {
		ExpressionFactory factory = new ExpressionFactoryImpl();
		SimpleContext context = new SimpleContext();
		for (String key : conditionMap.keySet()) {
			context.setVariable(key, factory.createValueExpression(conditionMap.get(key), String.class));
		}
		ValueExpression e = factory.createValueExpression(context, el, boolean.class);
		return (Boolean) e.getValue(context);
	}

//	/**
//	 * 根据key和value判断el表达式是否通过信息
//	 * @param key el表达式key信息
//	 * @param el el表达式信息
//	 * @param value el表达式传入值信息
//	 * @return
//	 */
//	public boolean isCondition(String key, String el, String value) {
//		ExpressionFactory factory = new ExpressionFactoryImpl();
//		SimpleContext context = new SimpleContext();
//		context.setVariable(key, factory.createValueExpression(value, String.class));
//		ValueExpression e = factory.createValueExpression(context, el, boolean.class);
//		return (Boolean) e.getValue(context);
//	}
	
//	/**
//	 * 根据与流程定义processDefinitionId获取当前节点的下一个任务节点
//	 * @param processDefinitionId 流程定义processDefinitionId
//	 * @param activityId 当前节点Id
//	 * @param elString 当前节点流向下一个节点的匹配字符串如下${pass}或者${!pass} 获取领导同意的userTask，则传入 ${pass}
//	 * @return
//	 */
//	public TaskDefinition getNextTaskDefinition(String processDefinitionId,String activityId,String elString,boolean flag){
//		try {
//			elString = URLDecoder.decode(elString,"UTF-8");
//		} catch (UnsupportedEncodingException e) {
//			throw new ExceptionUtil(e.getMessage(),e.getCause());
//		}
//		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
//		if (processDefinition != null) {
//			ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(processDefinition.getId());
//			ActivityImpl activityImpl = processDefinitionEntity.findActivity(activityId);
//			if (ActivitiUtil.USER_TASK.equals(activityImpl.getProperty("type")) && !flag) {
//				TaskDefinition taskDefinition = ((UserTaskActivityBehavior)activityImpl.getActivityBehavior()).getTaskDefinition();
//				return taskDefinition;
//			}else {
//				List<PvmTransition> pvmTransitions = activityImpl.getOutgoingTransitions();
//				List<PvmTransition> outpvmTransitions = null;
//				for(PvmTransition pvmTransition : pvmTransitions){
//					//获取所有的终点节点
//					PvmActivity pa = pvmTransition.getDestination();
//					if (ActivitiUtil.EXCLUSIVEGATEWAY.equals(pa.getProperty("type"))) {
//						outpvmTransitions = pa.getOutgoingTransitions();
//						if (outpvmTransitions.size() == 1) {
//							return getNextTaskDefinition(processDefinitionId, pa.getId(), elString, false);
//						}else if (outpvmTransitions.size() > 1) {
//							for (PvmTransition outPvmTransition : outpvmTransitions) {
//								Object object = outPvmTransition.getProperty("conditionText");//变量条件
//								if (elString.equals((object.toString().trim()))) {
//									PvmActivity pvmActivity = outPvmTransition.getDestination();
//									return getNextTaskDefinition(processDefinitionId, pvmActivity.getId(), elString, false);
//								}
//							}
//						}
//					}else if (ActivitiUtil.USER_TASK.equals(pa.getProperty("type"))) {
//						return ((UserTaskActivityBehavior)((ActivityImpl)pa).getActivityBehavior()).getTaskDefinition();
//					}
//				}
//			}
//		}
//		return null;
//	}
	
//	/**
//	 * 根据任务Id查找下一步PvmActivity
//	 * @param taskId
//	 * @return
//	 */
//	public List<PvmActivity> getNextTaskDefinition(String taskId){
//		List<PvmActivity> pvmActivityList = new ArrayList<PvmActivity>();
//		TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(taskId).singleResult();
//		ProcessDefinitionEntity def = (ProcessDefinitionEntity)((RepositoryServiceImpl)repositoryService).getDeployedProcessDefinition(task.getProcessDefinitionId());
//		List<ActivityImpl> activitiList = def.getActivities();
//		String excId = task.getExecutionId();
//		ExecutionEntity execution = (ExecutionEntity) runtimeService.createExecutionQuery().executionId(excId).singleResult();
//		String activitiId = execution.getActivityId();
//		for(ActivityImpl activityImpl:activitiList){
//			String id = activityImpl.getId();
//			if(activitiId.equals(id)){
//				//输出某个节点的某种属性
//				log.info("当前任务："+activityImpl.getProperty("name"));
//				//获取从某个节点出来的所有线路
//				List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();
//				for(PvmTransition pr:outTransitions){
//					PvmActivity pa = pr.getDestination();
//					pvmActivityList.add(pa);
//					//获取线路的终点节点
//					log.info("下一步任务："+pa.getProperty("name"));
//				}
//				break;
//			}
//		}
//		return pvmActivityList;
//	}
	
	/**
	 * 根据流程实例Id查找当前任务集合
	 * @param procInstanceId 流程实例Id
	 * @return
	 */
	public List<Task> getCurrentTaskListByProcessInstanceId(String procInstanceId){
		List<Task> tasks = taskService.createTaskQuery().processInstanceId(procInstanceId).list();
		return tasks;
	}

//    /**
//     * 根据流程实例Id查找当前任务
//     * @param procInstanceId 流程实例Id
//     * @return
//     */
//    public TaskEntity getCurrentTaskByProcessInstanceId(String procInstanceId){
//        TaskEntity taskEntity = (TaskEntity) taskService.createTaskQuery().processInstanceId(procInstanceId).singleResult();
//        return taskEntity;
//    }
	
//	/**
//	 * 根据当前节点获取下个节点为用户任务的所有节点编号
//	 * @param processInstance 流程实例id
//	 * @return
//	 */
//	public List<String> getNextTaskList(ProcessInstance processInstance){
//		List<String> taskIdList = new ArrayList<String>();
//		ProcessDefinitionEntity processDefinition1 = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
//		        .getDeployedProcessDefinition(processInstance.getProcessDefinitionId());
//		List<PvmActivity> pvmActivityList = new ArrayList<PvmActivity>();
//		List<ActivityImpl> activitiList = processDefinition1.getActivities();
//		for(ActivityImpl activityImpl:activitiList){
////			if (ActivitiUtil.USER_TASK.equals(activityImpl.getProperty("type"))) {
////				List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();
////				for(PvmTransition pr:outTransitions){
////					PvmActivity pa = pr.getDestination();
////					pa.getId();
////					pvmActivityList.add(pa);
////					//获取线路的终点节点
////					log.info("下一步任务："+pa.getProperty("name"));
////				}
////			}
//
//			List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();
//			for(PvmTransition pr:outTransitions){
//				PvmActivity pa = pr.getDestination();
//				pvmActivityList.add(pa);
//			}
//		}
//		for(PvmActivity pvmActivity:pvmActivityList){
//			if (ActivitiUtil.USER_TASK.equals(pvmActivity.getProperty("type"))) {
//				taskIdList.add(pvmActivity.getId());
//			}
//		}
//		return taskIdList;
//	}

	/**
	 * 获取当前所有活动节点 根据流程实例
	 * @param processInstance
	 * @return
	 */
	public List<ActivityImpl> getActivitiList(ProcessInstance processInstance){
		ProcessDefinitionEntity processDefinition1 = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)  
		        .getDeployedProcessDefinition(processInstance.getProcessDefinitionId());  
		List<ActivityImpl> activitiList = processDefinition1.getActivities();
		return activitiList;
	}
	
//	public List<Task> getTaskList(ProcessInstance processInstance){
//		ProcessDefinitionEntity processDefinition1 = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)  
//		        .getDeployedProcessDefinition(processInstance.getProcessDefinitionId());  
//		List<PvmActivity> pvmActivityList = new ArrayList<PvmActivity>();
//		List<ActivityImpl> activitiList = processDefinition1.getActivities();
//		for(ActivityImpl activityImpl:activitiList){
//			if (ActivitiUtil.USER_TASK.equals(activityImpl.getProperty("type"))) {
//				List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();
//				for(PvmTransition pr:outTransitions){
//					PvmActivity pa = pr.getDestination();
//					pvmActivityList.add(pa);
//					//获取线路的终点节点
//					log.info("下一步任务："+pa.getProperty("name"));
//				}
//			}
//		}
//	}
	
	/**
	 * 该方法可以参考使用 如获取节点表达式的变量值即BPM文件中定义的表达式相关变量值 如${SPR} 也可以拿到其中的SPR等
	 * API通过下个节点 获取节点中各个属性
	 * @param taskDefinition
	 */
	public void getNextTaskDefinition(TaskDefinition taskDefinition){
		Set<Expression>	setGroups = taskDefinition.getCandidateGroupIdExpressions();
		Set<Expression> setUsers = taskDefinition.getCandidateUserIdExpressions();
		Iterator<Expression> iterGroups = setGroups.iterator();
		Iterator<Expression> iterUsers = setUsers.iterator();
		List<String> alGroups = new ArrayList<String>();
		List<String> alUsers = new ArrayList<String>();
		while(iterGroups.hasNext()){
			Expression expression = iterGroups.next();
			alGroups.add(expression.getExpressionText());
		}
		while (iterUsers.hasNext()) {
			Expression expression = iterUsers.next();
			alUsers.add(expression.getExpressionText());
		}
		taskDefinition.getAssigneeExpression();
		taskDefinition.getCandidateUserIdExpressions();
		taskDefinition.getTaskListeners();
		taskDefinition.getTaskListener("");
		taskDefinition.getTaskFormHandler();
		taskDefinition.getPriorityExpression();
		taskDefinition.getKey();
		taskDefinition.getDueDateExpression();
		taskDefinition.getDescriptionExpression();
	}
	
	/**
	 * 查询所有实例
	 * @return
	 */
	public List<ProcessInstance> getProcessInstaceList(){
		List<ProcessInstance> list = runtimeService.createProcessInstanceQuery().list();
		return list;
	}
	
	/**
	 * 根据流程定义Key查找所有实例
	 * @param processDefinitionKey
	 * @return
	 */
	public List<ProcessInstance> getProcessInstaceListByDefinitionKey(String processDefinitionKey){
		List<ProcessInstance> list = runtimeService.createProcessInstanceQuery().processDefinitionKey(processDefinitionKey).list();  
		return list;
	}
	
	/**
	 * 根据流程定义id查找所有实例
	 * @param processDefinitionId
	 * @return
	 */
	public List<ProcessInstance> getProcessInstaceListById(String processDefinitionId){
		List<ProcessInstance> list = runtimeService.createProcessInstanceQuery().processDefinitionId(processDefinitionId).list();  
		return list;
	}
	
	/**
     * 查找活动任务
     * @return
     */
    public Map<String,Object> getProcessMap(ProcessInstance pi,ProcessDefinition processDefinition) {
    	Map<String,Object> map = new HashMap<String, Object>();
        List<ActivityImpl> actImpls = new ArrayList<ActivityImpl>();
        ProcessDefinitionImpl pdImpl = (ProcessDefinitionImpl) processDefinition;
        String processDefinitionId = pdImpl.getId();//流程标识
        ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(processDefinitionId);
        List<ActivityImpl> activitiList = def.getActivities();// 获得当前任务的所有节点
        List<String> ActiveActivityIds = runtimeService.getActiveActivityIds(pi.getId());
        for (String activeId : ActiveActivityIds) {
            for (ActivityImpl activityImpl : activitiList) {
                String id = activityImpl.getId();
                if (activityImpl.isScope()) {
                    if (activityImpl.getActivities().size() > 1) {
                        List<ActivityImpl> subAcList = activityImpl.getActivities();
                        for (ActivityImpl subActImpl : subAcList) {
                            String subid = subActImpl.getId();
                            if (activeId.equals(subid)) {// 获得执行到那个节点
                                actImpls.add(subActImpl);
                                break;
                            }
                        }
                    }
                }
                if (activeId.equals(id)) {// 获得执行到那个节点
                    actImpls.add(activityImpl);
                }
            }
        }
        map.put("actImpls", actImpls);
        map.put("activitiList", activitiList);
        return map;
    }

	/**
	 * 根据流程实例获取流程图并高亮（扩展写法）
	 * @param processInstanceId
	 * @return
	 */
	public List<ActivityImplEntity> getImageByInstance(String processInstanceId){
		List<ActivityImplEntity> activityImplEntities = new ArrayList<>();
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		if(null == processInstance){
			return activityImplEntities;
		}
		String processDefinitionId = processInstance.getProcessDefinitionId();
		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
		Map<String, Object> actMap = getProcessMap(processInstance,processDefinition);

		List<ActivityImpl> activities = (List<ActivityImpl>)actMap.get("actImpls");

		//版本一最合理
		for(ActivityImpl activity: activities){
			ActivityImplEntity activityImplEntity = new ActivityImplEntity(activity.getX(),activity.getY(),activity.getWidth(),activity.getHeight(),activity.getId());
			activityImplEntities.add(activityImplEntity);
		}


	    /*
	    获取流程图上每个节点信息
		List<ActivityImpl> activitiList = (List<ActivityImpl>)actMap.get("activitiList");
		map.put("activitiList", activitiList);
		*/
	    /* 原生态图片
	    String deploymentId = processDefinition.getDeploymentId();
	    String imageName = processDefinition.getDiagramResourceName();
	    InputStream resourceAsStream = repositoryService.getResourceAsStream(deploymentId, imageName);
	    String base64Img = ImageAnd64Binary.GetImageStr(resourceAsStream);
    	map.put("img", "data:image/png;base64," + base64Img);
    	*/
//		//版本二
//		ActivityImpl activity = activities.get(0);
//		int x = activity.getX();
//		int y = activity.getY();
//		int width = activity.getWidth();
//		int height = activity.getHeight();
//		map.put("x", x);
//		map.put("y", y);
//		map.put("width", width);
//		map.put("height", height);
//		map.put("id", activity.getId());
//		if(null == processInstance){
//			map.put("alive",false);
//		}else{
//			map.put("alive",true);
//		}
//		return map;
		return activityImplEntities;
	}

    
//    /**
//     * 根据流程实例获取流程图并高亮（废弃）
//     * @param processInstanceId
//     * @return
//     */
//    @Deprecated
//	public Map<String,Object> getImageByInstance(String processInstanceId){
//    	Map<String,Object> map = new HashMap<String, Object>();
//    	ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
//	    if(null == processInstance){
//	    	map.put("processInstance", null);
//	    	return map;
//	    }
//    	String processDefinitionId = processInstance.getProcessDefinitionId();
//	    ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
//	    Map<String, Object> actMap = getProcessMap(processInstance,processDefinition);
//
//	    List<ActivityImpl> activities = (List<ActivityImpl>)actMap.get("actImpls");
//
//	    /*
//	    获取流程图上每个节点信息
//		List<ActivityImpl> activitiList = (List<ActivityImpl>)actMap.get("activitiList");
//		map.put("activitiList", activitiList);
//		*/
//	    /* 原生态图片
//	    String deploymentId = processDefinition.getDeploymentId();
//	    String imageName = processDefinition.getDiagramResourceName();
//	    InputStream resourceAsStream = repositoryService.getResourceAsStream(deploymentId, imageName);
//	    String base64Img = ImageAnd64Binary.GetImageStr(resourceAsStream);
//    	map.put("img", "data:image/png;base64," + base64Img);
//    	*/
//	    // 不合理 并行网关 多任务节点高亮 则不满足
//		ActivityImpl activity = activities.get(0);
//		int x = activity.getX();
//		int y = activity.getY();
//		int width = activity.getWidth();
//		int height = activity.getHeight();
//	    map.put("x", x);
//	    map.put("y", y);
//	    map.put("width", width);
//        map.put("height", height);
//		map.put("id", activity.getId());
//        if(null == processInstance){
//        	map.put("alive",false);
//		}else{
//			map.put("alive",true);
//		}
//	    return map;
//    }
    
    /**
     * 根据流程定义获取流程图
     * @param deploymentId 流程部署id
	 * @param name
     * @return
     */
	public String getProcessImgEd(String deploymentId,String name){
    	Map<String,Object> map = new HashMap<String, Object>();
	    InputStream resourceAsStream = repositoryService.getResourceAsStream(deploymentId, name);
	    String base64Img = ImageAnd64Binary.GetImageStr(resourceAsStream);
	    return "data:image/png;base64," + base64Img;
    }
	
	/**
	 * 将组任务指定个人任务（该方法：检查该任务是否已经被认领，如果被认领则会抛出ActivitiTaskAlreadyClaimedException）
	 * taskId 任务id
	 * userId 用户id
	 */  
    public boolean claim(String taskId,String userId){  
    	try {
    		 taskService.claim(taskId, userId);  
    		 return true;
		} catch (Exception e) {
			throw new ExceptionUtil(e.getMessage(),e.getCause()); 
		}
    }

	/**
	 * 委派任务（普通节点加签）
	 * taskId 任务id
	 * userId 用户id
	 */
	public boolean delegateTask(String taskId,String userId){
		try {
			taskService.delegateTask(taskId, userId);
			return true;
		} catch (Exception e) {
			log.error("委派任务异常：{}",e);
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}

	/**
     * 设置任务组用户（前提：之前这个任务是组任务）
	 * taskId 任务id
	 * userId 用户id
     */  
    public boolean setAssignee(String taskId,String userId){  
    	try {
    		taskService.setAssignee(taskId, userId);   
   		 return true;
		} catch (Exception e) {
			log.error("设置任务组用户异常：{}",e);
			throw new ExceptionUtil(e.getMessage(),e.getCause()); 
		}
    }  
    

    /**
     * 设置任务的归属者
	 * taskId 任务id
	 * userId 用户id
     */
    public boolean setOwner(String taskId,String userId){
    	try {
    		taskService.setOwner(taskId, userId); 
   		 return true;
		} catch (Exception e) {
			log.error("设置任务的归属者异常：{}",e);
			throw new ExceptionUtil(e.getMessage(),e.getCause()); 
		}
    }
    
    /**
     * 向组任务中添加成员
	 * taskId 任务id
	 * userId 用户id
     */  
    public boolean addGroupUser(String taskId,String userId){  
    	try {
    		 taskService.addCandidateUser(taskId, userId);  
    		 return true;
		} catch (Exception e) {
			log.error("向组任务中添加成员异常：{}",e);
			throw new ExceptionUtil(e.getMessage(),e.getCause()); 
		}
    }  
    
    /**
     * 向组任务中删除成员
     * taskId 任务id
     * userId 用户id
     */  
    public boolean deleteGroupUser(String taskId,String userId){  
    	try {
    		taskService .deleteCandidateUser(taskId, userId);  
  		 return true;
		} catch (Exception e) {
			log.error("向组任务中删除成员异常：{}",e);
			throw new ExceptionUtil(e.getMessage(),e.getCause()); 
		}
    }   
	
	/**
	 * 查找个人任务
	 * @param condition
	 * @return
	 */
	public Map<String, Object> getAssigneeTaskPageList(Map<String, Object> condition){
		Map<String, Object> map = new HashMap<String, Object>();
		int start = new Integer(condition.get("start").toString());
		int pageSize = new Integer(condition.get("pageSize").toString());
		/**
		List<Task> list = taskService.createTaskQuery().orderByTaskCreateTime().asc().list();  
	    if (list != null && list.size() > 0) {  
	        for (Task task : list) {  
	            log.info("当前任务办理人：    " + task.getAssignee());  
	            log.info("任务类型：       " + task.getCategory());  
	            log.info("任务描述：       " + task.getDescription());  
	            log.info("任务执行ID： " + task.getExecutionId());  
	            log.info("表单key：      " + task.getFormKey());  
	            log.info("任务ID：       " + task.getId());  
	            log.info("任务名称：       " + task.getName());  
	            log.info("任务所有者：  " + task.getOwner());  
	            log.info("任务父ID：      " + task.getParentTaskId());  
	            log.info("任务优先级：  " + task.getPriority());  
	            log.info("流程定义的id：    " + task.getProcessDefinitionId());  
	            log.info("流程实例的id：    " + task.getProcessInstanceId());  
	            log.info("任务定义的key：   " + task.getTaskDefinitionKey());  
	            log.info("所有人ID：      " + task.getTenantId());  
	            log.info("任务创建时间： " + task.getCreateTime());  
	            log.info("任务委派状态： " + task.getDelegationState());  
	            log.info("持续时间：       " + task.getDueDate());  
	            log.info("任务流程变量： " + task.getProcessVariables());
	        }  
	    }  
	    **/
		List<Task> TaskList = taskService.createTaskQuery().taskAssignee(condition.get("assignee").toString()).listPage(start, pageSize);
		long count = taskService.createTaskQuery().taskAssignee(condition.get("assignee").toString()).count();
		map.put("TaskList", TaskList);
		map.put("TaskCount", count);
		return map;
	}
	
	/**
	 * 查找个人全部任务
	 * @param condition
	 * @return
	 */
	public List<Task> getAssigneeTaskList(Map<String, Object> condition){
		return taskService.createTaskQuery().taskAssignee(condition.get("assignee").toString()).list(); 
	}
	
	/**
	 * 查找候选人任务
	 * @param condition
	 * @return
	 */
	public Map<String, Object> getCandidateTaskPageList(Map<String, Object> condition){  
		Map<String, Object> map = new HashMap<String, Object>();
		int start = new Integer(condition.get("start").toString());
		int pageSize = new Integer(condition.get("pageSize").toString());
		List<Task> list = taskService.createTaskQuery().taskCandidateUser(condition.get("candidateUser").toString()).listPage(start, pageSize);
		long count = taskService.createTaskQuery().taskCandidateUser(condition.get("candidateUser").toString()).count();
		map.put("TaskList", list);
		map.put("TaskCount", count);
		return map;
	}  
	
	/**
	 * 查找处理组任务
	 * @param condition
	 * @return
	 */
	public Map<String, Object> getCandidateGroupTaskPageList(Map<String, Object> condition){ 
		Map<String, Object> map = new HashMap<String, Object>();
		int start = new Integer(condition.get("start").toString());
		int pageSize = new Integer(condition.get("pageSize").toString());
		List<Task> list = taskService.createTaskQuery().taskCandidateGroup(condition.get("candidateGroup").toString()).listPage(start, pageSize);
		long count = taskService.createTaskQuery().taskCandidateGroup(condition.get("candidateGroup").toString()).count(); 
        map.put("TaskList", list);
		map.put("TaskCount", count);
		return map;
	}
	
	/**
	 * 完成任务
	 * @param taskId 任务Id
	 */
	public boolean completeTask(String taskId){
		try {
			Task task = getTaskByTaskId(taskId);
			if(null == task){
				throw new ExceptionUtil("未能找到任务："+taskId);
			}
			if (DelegationState.PENDING == task.getDelegationState()) {//如果是委派任务则调用resolveTask
				resolveTask(taskId,null);//先resolve 然后完成
				taskService.complete(taskId);
			}else{
				taskService.complete(taskId);//普通任务
			}

//			HistoricTaskInstance historicTaskInstance = getTaskById(taskId);
//			if(null != historicTaskInstance){
//				taskService.complete(taskId);
//			}else{
//				throw new ExceptionUtil("未能找到任务："+taskId);
//			}
			return true;
		} catch (Exception e) {
			log.error("完成任务异常：{}",e);
			throw new ExceptionUtil(e.getMessage(),e.getCause()); 
		}
	}
	
	/**
	 * 判断流程实例是否已经结束（流程状态）
	 * @param processInstanceId 流程实例id
	 * @return
	 */
	public boolean isEnded(String processInstanceId) {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        return processInstance.isEnded();
    }
	
	/**
	 * 根据条件查找所有任务并分页
	 * @param condition
	 * @return
	 */
	public Map<String, Object> getTaskList(Map<String, Object> condition){
		Map<String, Object> map = new HashMap<String, Object>();
		int start = new Integer(condition.get("start").toString());
		int pageSize = new Integer(condition.get("pageSize").toString());
		Object taskName =  condition.get("taskName");
		Object transactors = condition.get("transactors");//经办人
		Object candidates = condition.get("candidates");//候选人
		Object groups = condition.get("group");//候选组
		Object owner =  condition.get("owner");//任务所属人
		TaskQuery taskQuery = taskService.createTaskQuery();
		if(null != taskName){
			taskQuery.taskNameLike("%" + String.valueOf(taskName) + "%");
		}
		if(null != transactors){
			taskQuery.taskAssignee(String.valueOf(transactors));
		}
		if(null != candidates){
			taskQuery.taskCandidateUser(String.valueOf(candidates));
		}
		if(null != groups){
			taskQuery.taskCandidateGroup(String.valueOf(groups));
		}
		if(null != owner){
			taskQuery.taskOwner(String.valueOf(owner));
		}
		List<Task> list = taskQuery.orderByTaskCreateTime().desc().listPage(start, pageSize);
		long count = taskQuery.count();
        map.put("TaskList", list);
		map.put("TaskCount", count);
		return map;
	}
	
	/**
	 * 根据流程实例Id下任务并分页
	 * @param condition
	 * @return
	 */
	public Map<String, Object> getTaskListByInstanceId(Map<String, Object> condition){
		Map<String, Object> map = new HashMap<String, Object>();
		int start = new Integer(condition.get("start").toString());
		int pageSize = new Integer(condition.get("pageSize").toString());
		String instanceId = ""+condition.get("instanceId");
		List<Task> list = taskService.createTaskQuery().orderByTaskCreateTime().desc().processInstanceId(instanceId).listPage(start, pageSize);
		long count = taskService.createTaskQuery().count(); 
        map.put("TaskList", list);
		map.put("TaskCount", count);
		return map;
	} 
	
    
    /** 
     * 会签动态增加会签人 待验证
     * @param taskId 当前任务Id
     * @param userCodes 会签人账号集合
     */  
    public boolean jointProcess(String taskId, List<String> userCodes) {
		boolean b = true;
		try {
			for (String userCode : userCodes) {
				TaskEntity task = (TaskEntity) taskService.newTask(IdGenerator.class.newInstance().getNextId());
				task.setAssignee(userCode);
				task.setName(findTaskById(taskId).getName() + "-会签");
				task.setProcessDefinitionId(findProcessDefinitionEntityByTaskId(taskId).getId());
				task.setProcessInstanceId(findProcessInstanceByTaskId(taskId).getId());
				task.setParentTaskId(taskId);
				task.setDescription("jointProcess");
				taskService.saveTask(task);
			}
		}catch (Exception e){
			log.error("会签异常：{}",e);
			b =false;
		}
       return b;
    }

//	/**
//	 *
//	 * @param jumpCmdEntity
//	 * @return
//	 */
//	public BaseResult jump(JumpCmdEntity jumpCmdEntity){
//		if(null == jumpCmdEntity){
//			log.info("JumpCmdEntity is null");
//			return new BaseResult("JumpCmdEntity is null",false);
//		}
//
//		ProcessInstance processInstance = null;
//		if(!StringUtil.isEmpty(jumpCmdEntity.getProcessInstanceId())){
//			//1.查找流程实例
//			processInstance = findProcessInstanceByTaskId(jumpCmdEntity.getTaskId());
//		}
//		if(null == processInstance && StringUtil.isEmpty(jumpCmdEntity.getTaskId())){
//			//如果流程实例查不到并且任务也没有传递值则停止操作
//			log.info("任务id为空");
//			return new BaseResult("任务id为空",false);
//		}
//		if(null == processInstance){
//			if(!StringUtil.isEmpty(jumpCmdEntity.getTaskId())){
//				processInstance = findProcessInstanceByTaskId(jumpCmdEntity.getTaskId());
//			}else{
//				log.info("任务id为空");
//				return new BaseResult("任务id为空",false);
//			}
//		}
//		List<Task> taskList = new ArrayList<>();
//		List<Task> tasks = new ArrayList<>();
//		//2.查找当前任务（可能存在集合）
//		int type = jumpCmdEntity.getType();
//		if (type == 0){//默认 确保只要执行跳转则需要删除当前其并行的实例（即执行跳转时候 删除当流程实例下正在运行的其它节点）
//			tasks = findTaskListByInstanceId(processInstance.getId());
//		} else if (type == 1){//删除并行任务非同一节点（如网关并行任务的时候，当出现多个任务的时候，如果其中一个节点上任务执行跳转其它节点时候 需删除其它节点任务 与会签有本质区别）
//			tasks = findTaskListByInstanceId(processInstance.getId());
//		}else if (type == 2){//2.删除同一节点多任务并行（在同一个任务节点如会签 在该节点生成多个任务的时候 如果当前一个节点要求跳转其它节点的时候 需要删除与其并行的任务）
//			tasks = findTaskListByKey(findProcessInstanceByTaskId(jumpCmdEntity.getTaskId()).getId(), findTaskById(jumpCmdEntity.getTaskId()).getTaskDefinitionKey());
//		}else if (type == 3){//3.驳回时删除其它并行任务（只要跳转都要删除与其同一实例中的）
//			tasks = findTaskListByKey(findProcessInstanceByTaskId(jumpCmdEntity.getTaskId()).getId(), findTaskById(jumpCmdEntity.getTaskId()).getTaskDefinitionKey());
//		}else{
//			return new BaseResult("未能找到正确类型",false);
//		}
//		taskList.addAll(tasks);
//		if(CollectionUtil.isEmpty(tasks)){
//			return new BaseResult("未能找到可用的任务",false);
//		}
//		//3.查找流程定义
//		ProcessDefinitionEntity processDefinitionEntity = getProcessDefinitionEntityByDefined(processInstance.getProcessDefinitionId());
//
//		//4.当前正在执行任务的节点
//		ActivityImpl currentActivity = (ActivityImpl)processDefinitionEntity.findActivity(processInstance.getActivityId());
//
//		//5.跳转的目标节点
//		ActivityImpl targetActivity = (ActivityImpl) processDefinitionEntity.findActivity(jumpCmdEntity.getActivityId());
//		((RuntimeServiceImpl)runtimeService).getCommandExecutor()
//				.execute(new Command<Void>() {
//					public Void execute(CommandContext commandContext) {
//						ExecutionEntity executionEntity = (ExecutionEntity) runtimeService
//								.createExecutionQuery().executionId(taskList.get(0).getExecutionId()).singleResult();
//						executionEntity.setActivity(currentActivity);
//						executionEntity.setEventSource(currentActivity);
//						//根据executionId 获取Task
//						for(Task task: taskList){
//							Iterator<TaskEntity> localIterator = Context.getCommandContext().getTaskEntityManager().findTasksByExecutionId(task.getExecutionId()).iterator();
//							while (localIterator.hasNext()) {
//								TaskEntity taskEntity = (TaskEntity) localIterator.next();
//								//删除任务
//								Context.getCommandContext().getTaskEntityManager().deleteTask(taskEntity, "并行任务", true);//这里如果传值是false的话，那么就会保留原有的历史任务信息，比如说A-B-C,A完成之后，正常走是到B，倘若我们A走完，直接跳到C的话，那么C做完之后，查询该流程的全过程节点任务就是A，B，C三条数据，如果写true，那么查询出来的数据就是A,B
//							}
//						}
//						executionEntity.executeActivity(targetActivity);  //设置任务执行对象
//						return null;
//					}
//				});
//		return new BaseResult("跳转节点成功",true);
//	}

//	/**
//	 * 驳回流程
//	 * @param lcReceiveParam
//	 * @return
//	 */
//	public BaseResult backProcess(LcReceiveParam lcReceiveParam) {
//		try{
//
//			if (StringUtils.isEmpty(lcReceiveParam.getActivityId())) {
//				throw new ExceptionUtil("驳回目标节点Id为空！");
//			}
//			JumpCmdEntity jumpCmdEntity = new JumpCmdEntity();
//			jumpCmdEntity.setActivityId(lcReceiveParam.getActivityId());
//			jumpCmdEntity.setProcessInstanceId(lcReceiveParam.getProcessInstanceId());
//			jumpCmdEntity.setTaskId(lcReceiveParam.getTaskId());
//			lcReceiveParam.setType(lcReceiveParam.getType());
//			return jump(jumpCmdEntity);
//		}catch (Exception e){
//			log.error("驳回流程异常：{}",e);
//			return new BaseResult("驳回流程失败",false);
//		}
//	}

//	/**
//     * 驳回流程
//     * @param taskId 当前任务Id
//     * @param activityId 驳回节点Id
//     * @param variables 流程存储参数
//    */
//    public boolean backProcess(String taskId, String activityId,Map<String, Object> variables) {
//		boolean b = true;
//        if (StringUtils.isEmpty(activityId)) {
//            throw new ExceptionUtil("驳回目标节点Id为空！");
//        }
//        try{
//			// 查找所有并行任务节点，同时驳回（注意这个是针对会签 原因是通过TaskDefinitionKey说明针对的是同一个节点开启多任务 如会签）
//			List<Task> taskList = findTaskListByKey(findProcessInstanceByTaskId(taskId).getId(), findTaskById(taskId).getTaskDefinitionKey());
//			for (Task task : taskList) {
//				commitProcess(task.getId(), variables, activityId);
//			}
//		}catch (Exception e){
//        	log.error("驳回流程异常：{}",e);
//        	b = false;
//		}
//        return b;
//    }

//	/**
//	 * 驳回流程并删除并行节点任务
//	 * @param taskId 当前任务Id
//	 * @param activityId 驳回节点Id
//	 * @param variables 流程存储参数
//	 */
//	public BaseResult backProcessAndDelParallelTask(String taskId, String activityId,Map<String, Object> variables) {
//		if (StringUtils.isEmpty(activityId)) {
//			throw new ExceptionUtil("驳回目标节点Id为空！");
//		}
//		try{
//			// 查找所有并行任务节点，同时驳回（注意这个是针对会签 原因是通过TaskDefinitionKey说明针对的是同一个节点开启多任务 如会签）
//			List<Task> taskList = findTaskListByInstanceId(findProcessInstanceByTaskId(taskId).getId());
//			for (Task task : taskList) {
//				commitProcess(task.getId(), variables, activityId);
//			}
//		}catch (Exception e){
//			log.error("驳回流程异常：{}",e);
//			return new BaseResult("驳回流程异常",false);
//		}
//		return new BaseResult("驳回流程成功",true);
//	}


//    /**
//     * 取回流程（缺点是如果没有连线的话无法取回 根据实际情况选择使用）
//     * @param taskId 当前任务Id
//     * @param activityId 取回节点Id
//     * @throws Exception
//     */
//    public boolean callBackProcess(String taskId, String activityId){
//		boolean b = true;
//		if (StringUtils.isEmpty(activityId)) {
//			throw new ExceptionUtil("目标节点Id为空！");
//		}
//		try{
//			// 查找所有并行任务节点，同时取回
//			List<Task> taskList = findTaskListByKey(findProcessInstanceByTaskId(taskId).getId(), findTaskById(taskId).getTaskDefinitionKey());
//			for (Task task : taskList) {
//				commitProcess(task.getId(), null, activityId);
//			}
//		}catch (Exception e){
//			log.error("取回流程异常：{}",e);
//			b = false;
//		}
//        return b;
//
//    }

//	/**
//     * 清空指定活动节点流向
//     * @param activityImpl 活动节点
//     * @return 节点流向集合
//     */
//    private List<PvmTransition> clearTransition(ActivityImpl activityImpl) {
//        //存储当前节点所有流向临时变量
//        List<PvmTransition> oriPvmTransitionList = new ArrayList<PvmTransition>();
//        //获取当前节点所有流向，存储到临时变量，然后清空
//        List<PvmTransition> pvmTransitionList = activityImpl.getOutgoingTransitions();
//        for (PvmTransition pvmTransition : pvmTransitionList) {
//            oriPvmTransitionList.add(pvmTransition);
//        }
//        pvmTransitionList.clear();
//        return oriPvmTransitionList;
//    }

//	/**
//	 * 提交流程
//     * @param taskId 当前任务Id
//     * @param variables 流程变量
//     * @param activityId 流程转向执行任务节点Id 此参数为空，默认为提交操作
//     */
//    private boolean commitProcess(String taskId, Map<String, Object> variables,String activityId){
//		boolean b = true;
//		try{
//			if (variables == null) {
//				variables = new HashMap<String, Object>();
//			}
//			// 跳转节点为空，默认提交操作
//			if (StringUtils.isEmpty(activityId)) {
//				taskService.complete(taskId, variables);
//			} else {// 流程转向操作
//				turnTransition(taskId, activityId, variables);
//			}
//		}catch (Exception e){
//			log.error("提交流程异常：{}",e);
//			b = false;
//			throw new ExceptionUtil("提交流程异常，{}",e);
//		}
//        return b;
//    }

    /**
     * 结束流程实例
     * @param lcReceiveNParam
     */
    public BaseResult termination(LcReceiveNParam lcReceiveNParam){
    	try{
			List<FlowElement> flowElements = null;
    	    if(!StringUtil.isEmpty(lcReceiveNParam.getTaskId())) {
    	    	HistoricTaskInstance historicTaskInstance = getTaskById(lcReceiveNParam.getTaskId());
    	    	if(null == historicTaskInstance){
    	    		log.error("未能获取到流程实例,{}",lcReceiveNParam);
    	    		throw new ExceptionUtil("未能获取到流程实例");
				}

//				runtimeService.deleteProcessInstance(historicTaskInstance.getId(), "强制终止流程实例");

				String processDefinitionId = historicTaskInstance.getProcessDefinitionId();
    	    	if(StringUtil.isEmpty(processDefinitionId)){
					log.error("未能获取到流程定义,{}",lcReceiveNParam);
					throw new ExceptionUtil("未能获取到流程定义");
				}

				flowElements = getFlowElementsOfType(processDefinitionId,EndEvent.class);
            }else if(!StringUtil.isEmpty(lcReceiveNParam.getProcessInstanceId())){//根据流程实例直接终止流程实例
    	        List<Task> tasks = getTaskListByProcessInstanceId(lcReceiveNParam.getProcessInstanceId());
    	        if(CollectionUtil.isEmpty(tasks)){
					log.error("根据流程实例id未能找到运行的任务,{}",lcReceiveNParam);
					throw new ExceptionUtil("根据流程实例id未能找到运行的任务");
				}
				lcReceiveNParam.setTaskId(tasks.get(0).getId());//需要将任务设置到参数中 原有jump需要taskid参数
				String processDefinitionId = tasks.get(0).getProcessDefinitionId();
				if(StringUtil.isEmpty(processDefinitionId)){
					log.error("未能获取到流程定义,{}",lcReceiveNParam);
					throw new ExceptionUtil("未能获取到流程定义");
				}
				flowElements = getFlowElementsOfType(processDefinitionId,EndEvent.class);
            }else{
    	        throw new ExceptionUtil("任务id流或程实例id至少有一项有值！");
            }

			if(CollectionUtil.isEmpty(flowElements)){
				log.error("未能获取到结束节点，无法终止流程实例,{}",lcReceiveNParam);
				throw new ExceptionUtil("未能获取到结束节点，无法终止流程实例");
			}
			//终止时 只需要找到一个结束目标节点 然后调用jump操作即可（jump暴力终止其它所有正在同一实例下的任务）
			for(FlowElement flowElement: flowElements){
				lcReceiveNParam.setActivityId(flowElement.getId());
				lcReceiveNParam.setEndAllActivityInstances(true);
				if(jump(lcReceiveNParam).getSuccess()){
					return new BaseResult("流程终止成功",true);
				}else{
					return new BaseResult("流程终止失败",false);
				}
			}
		}catch (Exception e){
    		log.error("中止流程异常：{}",e);
			return new BaseResult("流程终止失败",false);
		}
		return new BaseResult("流程终止成功",true);
    }

	/**
	 * 获取最近一次当前实例的任务 用于驳回方式采用默认使用
	 * @param lcReceiveParam
	 * @return
	 */
    public ActivityImpl getLastUserTaskActivityImpl(LcReceiveParam lcReceiveParam){
		if(null == lcReceiveParam){
			return null;
		}

		ActivityImpl lastActivity = null;
		List<HistoricActivityInstance> historicActivityInstances = null;
		String processInstanceId = null;
		if(!StringUtil.isEmpty(lcReceiveParam.getProcessInstanceId())){//如果流程实例id不为空 优先使用
			processInstanceId = lcReceiveParam.getProcessInstanceId();
		}
		if(StringUtil.isEmpty(processInstanceId) && !StringUtil.isEmpty(lcReceiveParam.getTaskId())){
			HistoricTaskInstance historicTaskInstance = getTaskById(lcReceiveParam.getTaskId());
			if(null != historicTaskInstance){
				processInstanceId = historicTaskInstance.getProcessInstanceId();
			}
		}
		if(!StringUtil.isEmpty(processInstanceId)){//如果流程实例id不为空 优先使用
			//查找上一个UserTask节点
			historicActivityInstances = historyService
					.createHistoricActivityInstanceQuery().activityType(ActivitiUtil.USER_TASK)
					.processInstanceId(processInstanceId)
					.finished()
					.orderByHistoricActivityInstanceEndTime().desc().list();
		}
		HistoricActivityInstance historicActivityInstance = null;
		if(!CollectionUtil.isEmpty(historicActivityInstances) && historicActivityInstances.size() > 0) {
			for(HistoricActivityInstance instance: historicActivityInstances){
				if(instance.getActivityId().equals(lcReceiveParam.getActivityId())){//过滤会签（否则会出现如下问题，当会签节点中第一个用户提交任务，第二个驳回，此时如果查找最近任务则就会将会签节点找到 这样就不正确，会一直重复在该节点）
					continue;
				}
				historicActivityInstance = instance;
				break;
			}
			ProcessDefinitionEntity processDefinitionEntity = getProcessDefinitionEntityByDefined(historicActivityInstance.getProcessDefinitionId());
			lastActivity = ((ProcessDefinitionImpl) processDefinitionEntity).findActivity(historicActivityInstance.getActivityId());
		}else{
			log.info("未能找到当前流程实例对应的最近一次用户任务节点,{}",lcReceiveParam);
		}
		return lastActivity;
	}

	/**
     * 根据流入任务集合，查询最近一次的流入任务节点
     * @param processInstance 流程实例
     * @param activities 流入任务集合
     * @return
     */
    private ActivityImpl filterNewestActivity(ProcessInstance processInstance,List<ActivityImpl> activities) {
        while (activities.size() > 0) {
            ActivityImpl activity_1 = activities.get(0);
            HistoricActivityInstance activityInstance_1 = findHistoricUserTask(processInstance, activity_1.getId());
            if (activityInstance_1 == null) {
				activities.remove(activity_1);
                continue;
            }
            if (activities.size() > 1) {
                ActivityImpl activity_2 = activities.get(1);
                HistoricActivityInstance activityInstance_2 = findHistoricUserTask(processInstance, activity_2.getId());
                if (activityInstance_2 == null) {
					activities.remove(activity_2);
                    continue;
                }
                if (activityInstance_1.getEndTime().before(activityInstance_2.getEndTime())) {
					activities.remove(activity_1);
                } else {
					activities.remove(activity_2);
                }
            } else {
                break;
            }
        }
        if (activities.size() > 0) {
            return activities.get(0);
        }
        return null;
    }


    /**
     * 根据任务Id和节点Id查找活动节点
     * @param taskId 任务Id
     * @param activityId 目标任务节点 活动节点Id如果为null或""，则默认查询当前活动节点 如果为"end"，则查询结束节点
     * @return
     */
    public ActivityImpl findActivitiImpl(String taskId, String activityId){
        // 取得流程定义
        ProcessDefinitionEntity processDefinition = findProcessDefinitionEntityByTaskId(taskId);
        // 获取当前活动节点ID
        if (StringUtils.isEmpty(activityId)) {
            activityId = findTaskById(taskId).getTaskDefinitionKey();
        }
        // 根据流程定义，获取该流程实例的结束节点
        if (activityId.toUpperCase().equals(ActivitiUtil.END)) {
            for (ActivityImpl activityImpl : processDefinition.getActivities()) {
                List<PvmTransition> pvmTransitionList = activityImpl
                        .getOutgoingTransitions();
                if (pvmTransitionList.isEmpty()) {
                    return activityImpl;
                }
            }
        }
        // 找不到节点 则根据节点Id，获取对应的活动节点
        ActivityImpl activityImpl = ((ProcessDefinitionImpl) processDefinition).findActivity(activityId);
        return activityImpl;
    }

    /**
     * 根据当前任务Id，查询可以驳回的任务节点
     * @param taskId 当前任务Id
     */
    public List<ActivityImpl> findCanBackActivity(String taskId) {
		List<ActivityImpl> activities = null;
		try{
			activities = iteratorBackActivity(taskId, findActivitiImpl(taskId, null), new ArrayList<ActivityImpl>(), new ArrayList<ActivityImpl>());
		}catch (Exception e){
    		log.error("查询可驳回任务节点异常：",e);
    		return activities;
		}
        return reverList(activities);
    }

    /**
     * 查询指定任务节点的最新记录
     * @param processInstance 流程实例
     * @param activityId 节点id（此处传的是任务id）
     * @return
    */
    public HistoricActivityInstance findHistoricUserTask(ProcessInstance processInstance, String activityId) {
        HistoricActivityInstance rtnVal = null;
        // 查询当前流程实例审批结束的历史节点
        List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery().activityType(ActivitiUtil.USER_TASK) //设置了userTask人工任务
                .processInstanceId(processInstance.getId()).activityId(activityId).finished()
                .orderByHistoricActivityInstanceEndTime().desc().list();
        if (historicActivityInstances.size() > 0) {
            rtnVal = historicActivityInstances.get(0);
        }
        return rtnVal;
    }

    /**
     * 根据当前节点，查询输出流向是否为并行终点，如果为并行终点，则拼装对应的并行起点Id
     * @param activityImpl 当前节点
     * @return
     */
    public String findParallelGatewayId(ActivityImpl activityImpl) {
        List<PvmTransition> incomingTransitions = activityImpl.getOutgoingTransitions();
        for (PvmTransition pvmTransition : incomingTransitions) {
            TransitionImpl transitionImpl = (TransitionImpl) pvmTransition;
            activityImpl = transitionImpl.getDestination();
            String type = (String) activityImpl.getProperty("type");
            if (ActivitiUtil.PARALLELGATEWAY.equals(type)) {
            	//并行路线
                String gatewayId = activityImpl.getId();
                String gatewayType = gatewayId.substring(gatewayId.lastIndexOf("_") + 1);
                if (ActivitiUtil.END.equals(gatewayType.toUpperCase())) {
                    return gatewayId.substring(0, gatewayId.lastIndexOf("_"))+ "_start";
                }
            }
        }
        return null;
    }

    /**
     * 根据任务id 查找流程定义
     * @param taskId 任务id
     * @return
     */
    public ProcessDefinitionEntity findProcessDefinitionEntityByTaskId(String taskId){
		TaskEntity taskEntity = null;
		String processDefinitionId = "";
    	try{
			taskEntity = findTaskById(taskId);
		}catch (Exception e){

		}
		if(null != taskEntity){
			processDefinitionId = taskEntity.getProcessDefinitionId();
		}else{
			HistoricTaskInstance historicTaskInstance = findTaskHisById(taskId);
			if(null != historicTaskInstance){
				processDefinitionId = historicTaskInstance.getProcessDefinitionId();
			}
		}
        // 取得流程定义
		if(StringUtil.isEmpty(processDefinitionId)){
			log.info("根据任务id未能找到流程定义!{}",taskId);
			throw new ExceptionUtil("根据任务id未能找到流程定义!");
		}
        ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(processDefinitionId);
        if (processDefinition == null) {
            throw new ExceptionUtil("流程定义未找到!");
        }
        return processDefinition;
    }

    /**
     * 根据任务id查找对应的流程实例
     * @param taskId 任务id
     * @return
     */
    public ProcessInstance findProcessInstanceByTaskId(String taskId) {
        // 找到流程实例
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(findTaskById(taskId).getProcessInstanceId()).singleResult();
        if (processInstance == null) {
            throw new ExceptionUtil("流程实例未找到!");
        }
        return processInstance;
    }

    /**
     * 根据任务id查找任务实例
     * @param taskId 任务id
     * @return
     */
    public TaskEntity findTaskById(String taskId){
        TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task == null) {
			throw new ExceptionUtil("任务实例未找到");
        }
        return task;
    }

	/**
	 * 根据任务id查找历史任务
	 * @param taskId 任务id
	 * @return
	 */
	public HistoricTaskInstance findTaskHisById(String taskId){
		HistoricTaskInstance taskInstance = historyService
				.createHistoricTaskInstanceQuery().taskId(taskId)
				.singleResult();
		return taskInstance;
	}

    /**
     * 根据流程实例id和任务key值查询所有同级任务集合（注意：该同级指的是多任务，如会签，表示该节点定义的时候 指定该节点为会签，key表示节点定义的编号）
     * @param processInstanceId 流程实例id
     * @param key bpm中节点定义的id编号 如task节点设置了id为userTask6023b261-6a2e-0aa7-4e2d-208771ad6faf
     * @return
     */
    public List<Task> findTaskListByKey(String processInstanceId, String key) {
        return taskService.createTaskQuery().processInstanceId(processInstanceId).taskDefinitionKey(key).list();
    }

	/**
	 * 根据流程实例id查找当前活动任务集合
	 * @param processInstanceId 流程实例id
	 * @return
	 */
	public List<Task> findTaskListByInstanceId(String processInstanceId) {
		List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstanceId).list();
		return tasks;
	}

    /**
     * 迭代循环流程树结构，查询当前节点可驳回的任务节点
     * @param taskId 当前任务ID
     * @param currActivity 当前活动节点
     * @param rtnList 存储回退节点集合
     * @param tempList 临时存储节点集合（存储一次迭代过程中的同级userTask节点）
     * @return 回退节点集合
     */
    public List<ActivityImpl> iteratorBackActivity(String taskId,
            ActivityImpl currActivity, List<ActivityImpl> rtnList,
            List<ActivityImpl> tempList) throws Exception {
        // 查询流程定义，生成流程树结构
        ProcessInstance processInstance = findProcessInstanceByTaskId(taskId);
        // 当前节点的流入来源
        List<PvmTransition> incomingTransitions = currActivity.getIncomingTransitions();
        // 条件分支节点集合，userTask节点遍历完毕，迭代遍历此集合，查询条件分支对应的userTask节点
        List<ActivityImpl> exclusiveGateways = new ArrayList<ActivityImpl>();
        // 并行节点集合，userTask节点遍历完毕，迭代遍历此集合，查询并行节点对应的userTask节点
        List<ActivityImpl> parallelGateways = new ArrayList<ActivityImpl>();
        // 遍历当前节点所有流入路径
        for (PvmTransition pvmTransition : incomingTransitions) {
            TransitionImpl transitionImpl = (TransitionImpl) pvmTransition;
            ActivityImpl activityImpl = transitionImpl.getSource();
            String type = (String) activityImpl.getProperty("type");
            /**
             * 并行节点配置要求：
             * 必须成对出现，且要求分别配置节点ID为:XXX_start(开始)，XXX_end(结束)
             */
            if (ActivitiUtil.PARALLELGATEWAY.equals(type)) {// 并行路线
                String gatewayId = activityImpl.getId();
                String gatewayType = gatewayId.substring(gatewayId.lastIndexOf("_") + 1);
                if (ActivitiUtil.START.equals(gatewayType.toUpperCase())) {
                	//并行起点，停止递归
                    return rtnList;
                } else {
                	//并行终点，临时存储此节点，本次循环结束，迭代集合，查询对应的userTask节点
                    parallelGateways.add(activityImpl);
                }
            } else if (ActivitiUtil.STARTEVENT.equals(type)) {
            	//开始节点，停止递归
                return rtnList;
            } else if (ActivitiUtil.USER_TASK.equals(type)) {
            	//用户任务
                tempList.add(activityImpl);
            } else if (ActivitiUtil.EXCLUSIVEGATEWAY.equals(type)) {
            	//分支路线，临时存储此节点，本次循环结束，迭代集合，查询对应的userTask节点
                currActivity = transitionImpl.getSource();
                exclusiveGateways.add(currActivity);
            }
        }
        /**
         * 迭代条件分支集合，查询对应的userTask节点
         */
        for (ActivityImpl activityImpl : exclusiveGateways) {
            iteratorBackActivity(taskId, activityImpl, rtnList, tempList);
        }
        /**
         * 迭代并行集合，查询对应的userTask节点
         */
        for (ActivityImpl activityImpl : parallelGateways) {
            iteratorBackActivity(taskId, activityImpl, rtnList, tempList);
        }
        /**
         * 根据同级userTask集合，过滤最近发生的节点
         */
        currActivity = filterNewestActivity(processInstance, tempList);
        if (currActivity != null) {
            //查询当前节点的流向是否为并行终点，并获取并行起点ID
            String id = findParallelGatewayId(currActivity);
            if (StringUtils.isEmpty(id)) {
            	//并行起点ID为空，此节点流向不是并行终点，符合驳回条件，存储此节点
                rtnList.add(currActivity);
            } else {
            	//根据并行起点ID查询当前节点，然后迭代查询其对应的userTask任务节点
                currActivity = findActivitiImpl(taskId, id);
            }
            // 清空本次迭代临时集合
            tempList.clear();
            // 执行下次迭代
            iteratorBackActivity(taskId, currActivity, rtnList, tempList);
        }
        return rtnList;
    }

//    /**
//     * 还原指定活动节点流向
//     * @param activityImpl 活动节点
//     * @param oriPvmTransitionList 原有节点流向集合
//     */
//    public void restoreTransition(ActivityImpl activityImpl,List<PvmTransition> oriPvmTransitionList) {
//        //清空现有流向
//        List<PvmTransition> pvmTransitionList = activityImpl.getOutgoingTransitions();
//        pvmTransitionList.clear();
//        //还原以前流向
//        for (PvmTransition pvmTransition : oriPvmTransitionList) {
//            pvmTransitionList.add(pvmTransition);
//        }
//    }

    /**
     * 反向排序list集合，便于驳回节点按顺序显示
     * @param list
     * @return
     */
    public List<ActivityImpl> reverList(List<ActivityImpl> list) {
        List<ActivityImpl> rtnList = new ArrayList<ActivityImpl>();
        //由于迭代出现重复数据，排除重复
        for (int i = list.size(); i > 0; i--) {
            if (!rtnList.contains(list.get(i - 1)))
                rtnList.add(list.get(i - 1));
        }
        return rtnList;
    }

    /**
     * 转办流程
     * @param taskId 当前任务节点Id
     * @param userId 被转办人Id
     */
    public void transferAssignee(String taskId, String userId) {
        taskService.setAssignee(taskId, userId);
    }

//    /**
//     * 流程转向
//     * @param taskId 当前任务Id
//     * @param activityId 目标节点任务Id
//     * @param variables 流程变量
//     */
//    public void turnTransition(String taskId, String activityId,Map<String, Object> variables) {
//    	try {
//			// 当前节点
//			ActivityImpl currActivity = findActivitiImpl(taskId, null);
//			// 清空当前流向
//			List<PvmTransition> oriPvmTransitionList = clearTransition(currActivity);
//			// 创建新流向
//			TransitionImpl newTransition = currActivity.createOutgoingTransition();
//			// 目标节点
//			ActivityImpl pointActivity = findActivitiImpl(taskId, activityId);
//			// 设置新流向的目标节点
//			newTransition.setDestination(pointActivity);
//			// 执行转向任务
//			taskService.complete(taskId, variables);
//			// 删除目标节点新流入
//			pointActivity.getIncomingTransitions().remove(newTransition);
//			// 还原以前流向
//			restoreTransition(currActivity, oriPvmTransitionList);
//		}catch (Exception e){
//			log.error("流程转向异常：{}",e);
//			throw new ExceptionUtil("流程转向异常：",e);
//		}
//    }

    /**
     * 验证登录
     */
	public boolean login(String userid, String password){
		return identityService.checkPassword(userid, password);
	}

	/**
	 * 获取用户详细信息
	 */
	public User getUserInfo(String userid) {
		return identityService.createUserQuery().userId(userid).singleResult();
	}

	/**
	 * 根据用户id查询用户所在的组
	 */
	public List<Group> getUserOfGroup(String userid) {
		return identityService.createGroupQuery().groupMember(userid).list();
	}


	/**
	 * 根据groupId查询组详细信息
	 */
	public Group getGroupInfo(String groupId) {
		return identityService.createGroupQuery().groupId(groupId).singleResult();
	}

	/**
	 * 列出组内的所有用户
	 */
	public List<User> memberOfGroup(String groupId) {
		return identityService.createUserQuery().memberOfGroup(groupId).list();
	}
	
	/**
	 * 根据流程实例id查找当前任务
	 * @param processInstanceId
	 * @return
	 */
	public Task getTaskByProcessInstanceId(String processInstanceId){
		if(validatePEnd(processInstanceId)){
			return null;
		}
		return taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
	}
	
	/**
	 * 发起开始动态表单 返回实例对象
	 * @param processDefinitionId
	 * @param properties
	 * @return
	 */
	public ProcessInstance submitStartFormData(String processDefinitionId, Map<String, String> properties){
		try {
			ProcessInstance processInstance = formService.submitStartFormData(processDefinitionId, properties);
			return processInstance;
		} catch (Exception e) {
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}

	/**
	 *  发起开始动态表单 返回实例对象
	 * @param processDefinitionId
	 * @param properties
	 * @return
	 */
	public ProcessInstance submitStartFormData(String processDefinitionId, String businessKey, Map<String, String> properties){
		try {
			ProcessInstance processInstance = formService.submitStartFormData(processDefinitionId, businessKey, properties);
			return processInstance;
		} catch (Exception e) {
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}
	
	/**
	 * 根据流程定义获取开始表单字段信息（即内容）
	 * @param processDefinitionId
	 * @return
	 */
	public StartFormData getStartFormData(String processDefinitionId){
		StartFormData startFormData = formService.getStartFormData(processDefinitionId);
		return startFormData;
	}
	
	/**
	 * 查找开始节点中表单属性集合
	 * @param startFormData
	 * @return
	 */
	public List<FormProperty> getStartFormProperties(StartFormData startFormData){
		return startFormData.getFormProperties();
	}

	/**
	 * 查找开始节点中表单属性集合
	 * @param processDefinitionId
	 * @return
	 */
	public List<FormProperty> getStartFormProperties(String processDefinitionId){
		StartFormData startFormData = getStartFormData(processDefinitionId);
		if(null != startFormData){
			return startFormData.getFormProperties();
		}
		return new ArrayList();
	}

	/**
	 * 根据taskId获取task节点中表单
	 * @param taskId
	 * @return
	 */
	public TaskFormData getTaskFormData(String taskId){
		return formService.getTaskFormData(taskId);
	}
	
	/**
	 * 查找task节点中表单属性集合
	 * @param taskFormData
	 * @return
	 */
	public List<FormProperty> getTaskFormProperties(TaskFormData taskFormData){
		return taskFormData.getFormProperties();
	}

	/**
	 * 查找task节点中表单属性集合
	 * @param taskId
	 * @return
	 */
	public List<FormProperty> getTaskFormProperties(String taskId){
		TaskFormData taskFormData = getTaskFormData(taskId);
		if(null != taskFormData){
			return taskFormData.getFormProperties();
		}
		return new ArrayList();
	}
	
	/**
	 * 发起任务动态表单
	 * @param processDefinitionId
	 * @param properties
	 * @return
	 */
	public void submitTaskFormData(String processDefinitionId, Map<String, String> properties){
		try {
			formService.submitTaskFormData(processDefinitionId, properties);
		} catch (Exception e) {
			log.error("发起任务动态表单异常：{}",e);
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}

	/**
	 * 根据流程实例id查找流程定义（相比较PProcessDefinitionEntity拿到的信息少）
	 * @param processInstanceId
	 * @return
	 */
	public ProcessDefinition getProcessDefinitionByInstanceId(String processInstanceId){
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		ProcessDefinition processDefinition = null;
		if(null != processInstance){
			processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processInstance.getProcessDefinitionId())
					.singleResult();
		}else{
			HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
			if(null != historicProcessInstance){
				processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(historicProcessInstance.getDeploymentId())
						.singleResult();
			}
		}
		return processDefinition;
	}

	/**
	 *  根据流程定义Id查找流程定义实体（相比较ProcessDefinition拿到的信息更多）
	 * @param definitionId
	 * @return
	 */
	public ProcessDefinitionEntity getProcessDefinitionEntityByDefined(String definitionId){
		ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(definitionId);
		return processDefinitionEntity;
	}

	/**
	 * 根据流程实例Id查找历史记录
	 * 如可以获取到实例运行时间
	 * @param processInstanceId
	 */
	public HistoricProcessInstance getHistoryProcessInstance(String processInstanceId) {
		HistoricProcessInstance hpi = historyService
				.createHistoricProcessInstanceQuery()//创建历史流程实例查询
				.processInstanceId(processInstanceId)
				.singleResult();
		log.info("流程定义ID："+hpi.getProcessDefinitionId());
		log.info("流程实例ID："+hpi.getId());
		log.info(hpi.getStartTime()+","+hpi.getEndTime()+","+hpi.getDurationInMillis());
		return hpi;
	}

//	/**
//	 * 根据流程实例Id下当前节点跳转到指定节点
//	 * @param jumpCmdEntity
//	 * @return
//	 */
//	public BaseResult excuteCurrentTaskJumpCmd(JumpCmdEntity jumpCmdEntity){
//		boolean b = true;
//		try{
//			if(StringUtil.isEmpty(jumpCmdEntity.getProcessInstanceId())){
//				throw new ExceptionUtil("流程实例id为空");
//			}
//			if(StringUtil.isEmpty(jumpCmdEntity.getActivityId())){
//				throw new ExceptionUtil("目标节点id为空");
//			}
//			//1.查找流程实例
//			ProcessInstance processInstance =  getProcessInstanceById(jumpCmdEntity.getProcessInstanceId());
//
//			List<Task> taskList = new ArrayList<>();
//			List<Task> tasks = new ArrayList<>();
//			//2.查找当前任务（可能存在集合）
//			int type = jumpCmdEntity.getType();
//			if (type == 0){//默认 确保只要执行跳转则需要删除当前其并行的实例（即执行跳转时候 删除当流程实例下正在运行的其它节点）
//				tasks = findTaskListByInstanceId(processInstance.getId());
//			} else if (type == 1){//删除并行任务非同一节点（如网关并行任务的时候，当出现多个任务的时候，如果其中一个节点上任务执行跳转其它节点时候 需删除其它节点任务 与会签有本质区别）
//				tasks = findTaskListByInstanceId(processInstance.getId());
//			}else if (type == 2){//2.删除同一节点多任务并行（在同一个任务节点如会签 在该节点生成多个任务的时候 如果当前一个节点要求跳转其它节点的时候 需要删除与其并行的任务）
//				tasks = findTaskListByKey(findProcessInstanceByTaskId(jumpCmdEntity.getTaskId()).getId(), findTaskById(jumpCmdEntity.getTaskId()).getTaskDefinitionKey());
//			}else if (type == 3){//3.驳回时删除其它并行任务（只要跳转都要删除与其同一实例中的）
//				tasks = findTaskListByKey(findProcessInstanceByTaskId(jumpCmdEntity.getTaskId()).getId(), findTaskById(jumpCmdEntity.getTaskId()).getTaskDefinitionKey());
//			}else{
//				return new BaseResult("未能找到正确类型",false);
//			}
//			taskList.addAll(tasks);
//			if(CollectionUtil.isEmpty(tasks)){
//				return new BaseResult("未能找到可用的任务",false);
//			}
//			//3.查找流程定义
//			ProcessDefinitionEntity processDefinitionEntity = getProcessDefinitionEntityByDefined(processInstance.getProcessDefinitionId());
//
//			//4.当前正在执行任务的节点
//			ActivityImpl currentActivity = (ActivityImpl)processDefinitionEntity.findActivity(processInstance.getActivityId());
//
//			//5.跳转的目标节点
//			ActivityImpl targetActivity = (ActivityImpl) processDefinitionEntity.findActivity(jumpCmdEntity.getActivityId());
//
////			((RuntimeServiceImpl)runtimeService).getCommandExecutor()
////				.execute(new Command<Void>() {
////					public Void execute(CommandContext commandContext) {
////						ExecutionEntity executionEntity = (ExecutionEntity) runtimeService
////								.createExecutionQuery().executionId(taskEntity.getExecutionId()).singleResult();
////						executionEntity.setActivity(currentActivity);
////						executionEntity.setEventSource(currentActivity);
////						//根据executionId 获取Task
////						Iterator<TaskEntity> localIterator = Context.getCommandContext().getTaskEntityManager().findTasksByExecutionId(taskEntity.getExecutionId()).iterator();
////						while (localIterator.hasNext()) {
////							TaskEntity taskEntity = (TaskEntity) localIterator.next();
////							//删除任务
////							Context.getCommandContext().getTaskEntityManager().deleteTask(taskEntity, jumpCmdEntity.getReason(), jumpCmdEntity.isCasCade());//这里如果传值是false的话，那么就会保留原有的历史任务信息，比如说A-B-C,A完成之后，正常走是到B，倘若我们A走完，直接跳到C的话，那么C做完之后，查询该流程的全过程节点任务就是A，B，C三条数据，如果写true，那么查询出来的数据就是A,B
////						}
////						executionEntity.executeActivity(targetActivity);  //设置任务执行对象
////						return null;
////					}
////				});
//
//			((RuntimeServiceImpl)runtimeService).getCommandExecutor()
//				.execute(new Command<Void>() {
//					public Void execute(CommandContext commandContext) {
//						ExecutionEntity executionEntity = (ExecutionEntity) runtimeService
//								.createExecutionQuery().executionId(taskList.get(0).getExecutionId()).singleResult();
//						executionEntity.setActivity(currentActivity);
//						executionEntity.setEventSource(currentActivity);
//
//						for(Task task: taskList){
//							//根据executionId 获取Task
//							Iterator<TaskEntity> localIterator = Context.getCommandContext().getTaskEntityManager().findTasksByExecutionId(task.getExecutionId()).iterator();
//							while (localIterator.hasNext()) {
//								TaskEntity taskEntity = (TaskEntity) localIterator.next();
//								//删除任务
//								Context.getCommandContext().getTaskEntityManager().deleteTask(taskEntity, jumpCmdEntity.getReason(), jumpCmdEntity.isCasCade());//这里如果传值是false的话，那么就会保留原有的历史任务信息，比如说A-B-C,A完成之后，正常走是到B，倘若我们A走完，直接跳到C的话，那么C做完之后，查询该流程的全过程节点任务就是A，B，C三条数据，如果写true，那么查询出来的数据就是A,B
//							}
//						}
//						executionEntity.executeActivity(targetActivity);  //设置任务执行对象
//						return null;
//					}
//				});
//		}catch (Exception e){
//			log.error("跳转节点异常：{}",e);
//			return new BaseResult("跳转节点失败",false);
//		}
//		return new BaseResult("跳转节点成功",true);
//	}

//	/**
//	 * 根据流程实例Id+指定任务id下指定任务节点跳转到指定节点
//	 * @param jumpCmdEntity
//	 * @return
//	 */
//	public boolean excuteJumpTaskCmd(JumpCmdEntity jumpCmdEntity){
//		boolean b = true;
//		try{
//			if(StringUtil.isEmpty(jumpCmdEntity.getProcessInstanceId())){
//				throw new ExceptionUtil("流程实例id为空");
//			}
//			if(StringUtil.isEmpty(jumpCmdEntity.getActivityId())){
//				throw new ExceptionUtil("目标节点id为空");
//			}
//			if(StringUtil.isEmpty(jumpCmdEntity.getTaskId())){
//				throw new ExceptionUtil("任务节点id为空");
//			}
//			//1.查找流程实例
//			ProcessInstance processInstance =  getProcessInstanceById(jumpCmdEntity.getProcessInstanceId());
//
//			//2.查找起始任务（即当前执行人所在的任务节点）
//			HistoricTaskInstance historicTaskInstance = getTaskById(jumpCmdEntity.getTaskId());//特定任务id
//
//			//3.查找流程定义
//			ProcessDefinitionEntity processDefinitionEntity = getProcessDefinitionEntityByDefined(processInstance.getProcessDefinitionId());
//
//			//4.当前正在执行任务的节点
//			ActivityImpl currentActivity = (ActivityImpl)processDefinitionEntity.findActivity(processInstance.getActivityId());
//
//			//5.跳转的目标节点
//			ActivityImpl targetActivity = (ActivityImpl) processDefinitionEntity.findActivity(jumpCmdEntity.getActivityId());
//
//			//6.指定任务节点
//			TaskEntity taskEntity = findTaskById(jumpCmdEntity.getTaskId());
//
//			((RuntimeServiceImpl)runtimeService).getCommandExecutor()
//					.execute(new Command<Void>() {
//						public Void execute(CommandContext commandContext) {
//							ExecutionEntity executionEntity = (ExecutionEntity) runtimeService
//									.createExecutionQuery().executionId(taskEntity.getExecutionId()).singleResult();
//							executionEntity.setActivity(currentActivity);
//							executionEntity.setEventSource(currentActivity);
//							//根据executionId 获取Task
//							Iterator<TaskEntity> localIterator = Context.getCommandContext().getTaskEntityManager().findTasksByExecutionId(historicTaskInstance.getExecutionId()).iterator();
//							while (localIterator.hasNext()) {
//								TaskEntity taskEntity = (TaskEntity) localIterator.next();
//								//删除任务
//								Context.getCommandContext().getTaskEntityManager().deleteTask(taskEntity, jumpCmdEntity.getReason(), jumpCmdEntity.isCasCade());//这里如果传值是false的话，那么就会保留原有的历史任务信息，比如说A-B-C,A完成之后，正常走是到B，倘若我们A走完，直接跳到C的话，那么C做完之后，查询该流程的全过程节点任务就是A，B，C三条数据，如果写true，那么查询出来的数据就是A,B
//							}
//							executionEntity.executeActivity(targetActivity);  //设置任务执行对象
//							return null;
//						}
//					});
//		}catch (Exception e){
//			log.error("跳转节点异常：{}",e);
//		}
//		return b;
//	}

	/**
	 *  根据流程实例查找所有任务节点
	 * @param processInstanceId
	 * @return
	 */
	public List<Task> getTaskListByProcessInstanceId(String processInstanceId){
		List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstanceId).list();
		return tasks;
	}

	/**
	 *  根据流程实例查找所有任务节点
	 * @param processInstanceId
	 * @return
	 */
	public List<HistoricTaskInstance> getHistoricTaskInstanceListByProcessInstanceId(String processInstanceId){
		List<HistoricTaskInstance> historicTaskInstances = historyService
				.createHistoricTaskInstanceQuery() // 创建历史任务实例查询
				.processInstanceId(processInstanceId) // 用流程实例id查询
//				.finished() // 查询已经完成的任务
				.list();
		return historicTaskInstances;
	}

	/**
	 * 根据流程实例 查找所有节点
	 * @param processInstanceId
	 * @return
	 */
	public Collection getFlowElementsByProcessInstanceId(String processInstanceId){
		String processDefinitionId = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId();
		BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
		Process process = bpmnModel.getProcesses().get(0);
		//获取所有节点
		Collection flowElements = process.getFlowElements();
		return flowElements;
	}

	/**
	 * 根据流程实例 查找所有任务节点
	 * @param processInstanceId
	 * @return
	 */
	public List<UserTask> getUserTaskByProcessInstanceId(String processInstanceId){
		String processDefinitionId = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId();
		BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
		Process process = bpmnModel.getProcesses().get(0);
		List<UserTask> UserTaskList = process.findFlowElementsOfType(UserTask.class);
		return UserTaskList;
	}

//    /**
//     * 根据流程实例Id 或任务 taskId 查找所有结束节点
//     * @param lcReceiveParam
//     * @return
//     */
//    public List<EndEvent> getEndActivityImplByProcessInstanceId(LcReceiveParam lcReceiveParam){
//        String processDefinitionId = "";
//        if(!StringUtil.isEmpty(lcReceiveParam.getProcessDefinitionId())){
//            processDefinitionId = lcReceiveParam.getProcessDefinitionId();
//            return getEndActivityImplByProcessDefinitionId(processDefinitionId);
//        }
//        if(!StringUtil.isEmpty(lcReceiveParam.getProcessInstanceId())){
//            processDefinitionId = runtimeService.createProcessInstanceQuery().processInstanceId(lcReceiveParam.getProcessInstanceId()).singleResult().getProcessDefinitionId();
//            return getEndActivityImplByProcessDefinitionId(processDefinitionId);
//        }
//        if(!StringUtil.isEmpty(lcReceiveParam.getActivityId())){
//            processDefinitionId = getTaskById(lcReceiveParam.getActivityId()).getProcessDefinitionId();
//            return getEndActivityImplByProcessDefinitionId(processDefinitionId);
//        }
//        return null;
//    }

//    /**
//     * 根据流程实定义查找所有结束节点
//     * @param processDefinitionId
//     * @return
//     */
//    public List<EndEvent> getEndActivityImplByProcessDefinitionId(String processDefinitionId){
//        if(StringUtil.isEmpty(processDefinitionId)){
//            return null;
//        }
//        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
//        Process process = bpmnModel.getProcesses().get(0);
//        List<EndEvent> endEvents = process.findFlowElementsOfType(EndEvent.class);
//        return endEvents;
//    }

    /**
     * 根据活动节点输出节点类型
     * @param activity
     * @return
     */
    public ActivityImplPropertiesEntity getActivityImplType(ActivityImpl activity){
        ActivityImplPropertiesEntity activityImplPropertiesEntity = new ActivityImplPropertiesEntity();
        Map<String,Object> prop = activity.getProperties();
        Iterator<String> keys = prop.keySet().iterator();
        while(keys.hasNext()){
            String key = keys.next();
            if(key.equals("type")){
                activityImplPropertiesEntity.setKey(key);
                activityImplPropertiesEntity.setValue(""+prop.get(key));
                activityImplPropertiesEntity.setId(activity.getId());
            }
        }
        return activityImplPropertiesEntity;
    }

	/**
	 * 删除历史流程任务记录
	 * @param taskId
	 * @return
	 */
	public boolean deleteHistoricTaskInstance(String taskId){
		boolean b = true;
		if(StringUtil.isEmpty(taskId)){
			throw new ExceptionUtil("任务id不能为空");
		}
		try{
			historyService.deleteHistoricTaskInstance(taskId);
		}catch (Exception e){
			log.error("删除历史任务异常：{}",e);
			b = false;
		}
		return b;
	}


	/**
	 * 根据部署Id 查找部署详情
	 * @param deploymentId
	 * @return
	 */
	public Deployment getDeploymentById(String deploymentId){
		Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult();
		return deployment;
	}

	/**
	 * 根据任务Id查找部署对象
	 * @param taskId
	 * @return
	 */
	public Deployment getDeploymentByTaskId(String taskId){
		HistoricTaskInstance historicTaskInstance = getTaskById(taskId);
		if(null == historicTaskInstance){
			log.info("未能查找到流程实例,任务编号：{}",taskId);
			throw new ExceptionUtil("未能查找到流程实例"+taskId);
		}
		String definitionId = historicTaskInstance.getProcessDefinitionId();
		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(definitionId).singleResult();
		String deploymentId = processDefinition.getDeploymentId();
		Deployment deployment = getDeploymentById(deploymentId);
		return deployment;
	}

	/**
	 * 根据任务Id查找部署Id
	 * @param taskId
	 * @return
	 */
	public String getDeploymentIdByTaskId(String taskId){
		HistoricTaskInstance historicTaskInstance = getTaskById(taskId);
		if(null == historicTaskInstance){
			log.info("未能查找到流程实例,任务编号：{}",taskId);
			throw new ExceptionUtil("未能查找到流程实例"+taskId);
		}
		String definitionId = historicTaskInstance.getProcessDefinitionId();
		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(definitionId).singleResult();
		String deploymentId = processDefinition.getDeploymentId();
		return deploymentId;
	}

	/**
	 * 判断节点是否为多实例节点（如会签，子流程）
	 * @param lcReceiveParam
	 * @return
	 */
	public boolean validateNodeIsMultiInstance(LcReceiveParam lcReceiveParam){
		ProcessDefinitionEntity processDefinitionEntity = null;
		ActivityImpl activityImpl = null;
		//两种情况1.根据任务id直接可以判断其节点是否为多实例,2根据流程实例id+节点id（即流程定义中的节点id号）判断是否为多实例
		if(!StringUtil.isEmpty(lcReceiveParam.getTaskId())){//cas1.根据任务id直接可以判断其节点是否为多实例
			HistoricTaskInstance historicTaskInstance = getTaskById(lcReceiveParam.getTaskId());
			if(null != historicTaskInstance){
				processDefinitionEntity = getProcessDefinitionEntityByDefined(historicTaskInstance.getProcessDefinitionId());
				if(StringUtil.isEmpty(lcReceiveParam.getActivityId())){
					activityImpl = processDefinitionEntity.findActivity(historicTaskInstance.getTaskDefinitionKey());
				}else{
					activityImpl = (ActivityImpl)processDefinitionEntity.findActivity(lcReceiveParam.getActivityId());
				}
			}
		}else {//cas2.根据流程实例id+节点id（即流程定义中的节点id号）判断是否为多实例
			if(!StringUtil.isEmpty(lcReceiveParam.getProcessInstanceId())){
				ProcessInstance processInstance = getProcessInstanceById(lcReceiveParam.getProcessInstanceId());
				if(null != processInstance){
					processDefinitionEntity = getProcessDefinitionEntityByDefined(processInstance.getProcessDefinitionId());
				}
			}
			// 根据活动id获取活动实例
			activityImpl = (ActivityImpl)processDefinitionEntity.findActivity(lcReceiveParam.getActivityId());
		}
		if(null == activityImpl){
			log.warn("判断节点是否为多实例节点时，出现未能获取到activityImpl对象，参数信息：{}",lcReceiveParam);
			throw new ExceptionUtil("判断节点是否为多实例节点时，出现未能获取到activityImpl对象");
		}
		if(((ActivityImpl) activityImpl).getActivityBehavior() instanceof ParallelMultiInstanceBehavior) {//并行多实例
			ParallelMultiInstanceBehavior behavior = (ParallelMultiInstanceBehavior) activityImpl.getActivityBehavior();
			if (behavior != null && behavior.getCollectionExpression() != null) {
				return true;
			}
		}
		if(((ActivityImpl) activityImpl).getActivityBehavior() instanceof SequentialMultiInstanceBehavior) {//串行多实例
			SequentialMultiInstanceBehavior behavior = (SequentialMultiInstanceBehavior) activityImpl.getActivityBehavior();
			if (behavior != null && behavior.getCollectionExpression() != null) {
				return true;
			}
		}
		return false;
	}


	/**
	 * 根据UserTask判断是否会签节点
	 * @param userTask
	 * @return
	 */
	public boolean validateNodeIsMultiInstance(UserTask userTask){
		boolean isMultiInstanceNode = userTask.getLoopCharacteristics() != null;
		return isMultiInstanceNode;
	}

	/**
	 * 动态设置节点表达式（谨慎使用）
	 * @param multiInstanceLoopCharacteristics
	 * @param collectionExpression
	 */
	public void setMultiInstanceLoopCharacteristics(MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics,String collectionExpression){
		multiInstanceLoopCharacteristics.setInputDataItem(collectionExpression);
	}

	/**
	 * 设置会签规则（效果等同于设计器中动态设置，优势可以动态更改规则）
	 * @param userTask
	 * @param lcNodeAttribute
	 */
	public void setMutilRule(UserTask userTask,LcNodeAttribute lcNodeAttribute){
		if(null == userTask){
			return;
		}
		if(null == lcNodeAttribute){
			return;
		}
		MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics1 = new MultiInstanceLoopCharacteristics();
		multiInstanceLoopCharacteristics1.setLoopCardinality(null);
		multiInstanceLoopCharacteristics1.setCompletionCondition("${nrOfActiveInstances == nrOfInstances}");
		multiInstanceLoopCharacteristics1.setSequential(false);
		userTask.setLoopCharacteristics(multiInstanceLoopCharacteristics1);
		List<LcNodeCandidate> lcNodeCandidates = lcNodeAttribute.getLcNodeCandidate();
		if(!CollectionUtil.isEmpty(lcNodeCandidates)){
			LcNodeCandidate lcNodeCandidate = lcNodeCandidates.get(0);
			if(null != lcNodeCandidate){
				if(!StringUtil.isEmpty(lcNodeCandidate.getCandidate_id())){
					//候选人
					List<String> list = Arrays.asList(lcNodeCandidate.getCandidate_id().split(","));
					userTask.setCandidateUsers(list);
				}
				if(!StringUtil.isEmpty(lcNodeCandidate.getAssignee_id())){
					//办理人
					userTask.setAssignee(lcNodeCandidate.getAssignee_id());
				}
				if(!StringUtil.isEmpty(lcNodeCandidate.getCandidate_group_id())){
					//组任务
					List<String> list = Arrays.asList(lcNodeCandidate.getCandidate_group_id().split(","));
					userTask.setCandidateGroups(list);
				}
			}
		}
	}

	/**
	 * 查询会签节点表达式
	 * @param userTask
	 * @return
	 */
	public String getCollectionExpression(UserTask userTask){
		if(null == userTask){
			return null;
		}
		String assigneeListExpression = userTask.getLoopCharacteristics().getInputDataItem();
		return assigneeListExpression;
	}

	/**
	 * 根据“任务id”或”根据流程实例id+节点id（即流程定义中的节点id号）“ 查找节点
	 * @param lcReceiveParam
	 * @return
	 */
	public ActivityImpl getActivityImpl(LcReceiveParam lcReceiveParam){
		ProcessDefinitionEntity processDefinitionEntity = null;
		ActivityImpl activityImpl = null;
		//两种情况1.根据任务id直接可以判断其节点是否为多实例,2根据流程实例id+节点id（即流程定义中的节点id号）判断是否为多实例
		if(!StringUtil.isEmpty(lcReceiveParam.getTaskId())){//cas1.根据任务id直接可以判断其节点是否为多实例
			HistoricTaskInstance historicTaskInstance = getTaskById(lcReceiveParam.getTaskId());
			if(null != historicTaskInstance){
				processDefinitionEntity = getProcessDefinitionEntityByDefined(historicTaskInstance.getProcessDefinitionId());
				activityImpl = processDefinitionEntity.findActivity(historicTaskInstance.getTaskDefinitionKey());
			}
		}else {//cas2.根据流程实例id+节点id（即流程定义中的节点id号）判断是否为多实例
			if(!StringUtil.isEmpty(lcReceiveParam.getProcessInstanceId())){
				ProcessInstance processInstance = getProcessInstanceById(lcReceiveParam.getProcessInstanceId());
				if(null != processInstance){
					processDefinitionEntity = getProcessDefinitionEntityByDefined(processInstance.getProcessDefinitionId());
				}
			}
			// 根据活动id获取活动实例
			activityImpl = (ActivityImpl)processDefinitionEntity.findActivity(lcReceiveParam.getActivityId());
		}
		return activityImpl;
	}

	/**
	 * 查找行为属性
	 * @param activityImpl
	 * @return
	 */
	public BehaviorEntity getMultiBehavior(ActivityImpl activityImpl){
		BehaviorEntity behaviorEntity = new BehaviorEntity();
		if(null == activityImpl){
			log.warn("查找行为属性异常：{}",activityImpl);
			throw new ExceptionUtil("查找行为属性异常，activityImpl为空");
		}
		if(((ActivityImpl) activityImpl).getActivityBehavior() instanceof ParallelMultiInstanceBehavior) {//并行多实例
			ParallelMultiInstanceBehavior behavior = (ParallelMultiInstanceBehavior) activityImpl.getActivityBehavior();
			if (behavior != null && behavior.getCollectionExpression() != null) {
				behaviorEntity.setCollectionElementIndexVariable(behavior.getCollectionElementIndexVariable());
				behaviorEntity.setCollectionElementVariable(behavior.getCollectionElementVariable());
				behaviorEntity.setCollectionElementIndexVariable(behavior.getCollectionElementIndexVariable());
				behaviorEntity.setCollectionExpressionText(behavior.getCollectionExpression().getExpressionText());
			}
		}
		if(((ActivityImpl) activityImpl).getActivityBehavior() instanceof SequentialMultiInstanceBehavior) {//串行多实例
			SequentialMultiInstanceBehavior behavior = (SequentialMultiInstanceBehavior) activityImpl.getActivityBehavior();
			if (behavior != null && behavior.getCollectionExpression() != null) {
				behaviorEntity.setCollectionElementIndexVariable(behavior.getCollectionElementIndexVariable());
				behaviorEntity.setCollectionElementVariable(behavior.getCollectionElementVariable());
				behaviorEntity.setCollectionElementIndexVariable(behavior.getCollectionElementIndexVariable());
				behaviorEntity.setCollectionExpressionText(behavior.getCollectionExpression().getExpressionText());
			}
		}else if(((ActivityImpl) activityImpl).getActivityBehavior() instanceof UserTaskActivityBehavior){
			TaskActivityBehavior taskActivityBehavior = ((UserTaskActivityBehavior) ((ActivityImpl) activityImpl).getActivityBehavior());
//			behaviorEntity.setCollectionElementIndexVariable(taskActivityBehavior.getMultiInstanceActivityBehavior().ge);
//			behaviorEntity.setCollectionElementVariable(taskActivityBehavior.getCollectionElementVariable());
//			behaviorEntity.setCollectionElementIndexVariable(taskActivityBehavior.getCollectionElementIndexVariable());
//			behaviorEntity.setCollectionExpressionText(taskActivityBehavior.getCollectionExpression().getExpressionText());
		}
		return behaviorEntity;
	}

//	/**
//	 * 根据TaskId查找下个节点是否会签并返回会签属性
//	 * @param taskId 任务id
//	 */
//	public void nextNodeIsMultiInstance(String taskId){
//		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
//		ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl)repositoryService).getDeployedProcessDefinition(task.getProcessDefinitionId());
//		List<ActivityImpl> activitiList = def.getActivities();
//		ExecutionEntity execution=(ExecutionEntity) runtimeService.createExecutionQuery().executionId(task.getExecutionId()).processInstanceId(task.getProcessInstanceId()).singleResult();
//		String activitiId = execution.getActivityId();
//		for(ActivityImpl activityImpl:activitiList){
//			String id = activityImpl.getId();
//			if(activitiId.equals(id)){
//				log.info("当前任务：{}",activityImpl.getProperty("name")); //输出某个节点的某种属性
//				List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();//获取从某个节点出来的所有线路
//				for(PvmTransition tr:outTransitions){
//					PvmActivity ac = tr.getDestination(); //获取线路的终点节点
//					String s=(String) ac.getProperty("multiInstance");
//					if("parallel".equals(s)){
//						String targetUserTaskId= ac.getId();
//						BpmnModel bpmnModel = repositoryService.getBpmnModel(def.getId());
//						List<Process> processes = bpmnModel.getProcesses();
//						for (Process process : processes) {
//							List<UserTask> userTaskList = process.findFlowElementsOfType(UserTask.class);
//							for (UserTask userTask : userTaskList) {
//								if(userTask.getId().equals(targetUserTaskId)){
//									List<String> candidateUsers = userTask.getCandidateUsers();
//									System.out.println(candidateUsers);
//								}
//							}
//						}
//					}
//				}
//			}
//		}
//	}


	/**
	 * 获取当前任务节点流出线名称集合（可用于在办理任务节点操作进行驳回或通过）
	 * @param taskId
	 * @return
	 */
	public List getOutTransListByTaskId(String taskId) {
		List<String> list = new ArrayList();
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();//使用任务ID，查询任务对象
		String processDefinitionId = task.getProcessDefinitionId();//获取流程定义ID
		ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(processDefinitionId);//查询ProcessDefinitionEntiy对象
		String processInstanceId = task.getProcessInstanceId();//使用任务对象Task获取流程实例ID
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();//使用流程实例ID，查询正在执行的执行对象表，返回流程实例对象
		String activityId = processInstance.getActivityId();//获取当前活动的id
		ActivityImpl activityImpl = processDefinitionEntity.findActivity(activityId);//获取当前的活动
		List<PvmTransition> pvmList = activityImpl.getOutgoingTransitions();//获取当前活动完成之后连线的名称
		if(pvmList!=null && pvmList.size()>0){
			for(PvmTransition pvmTransition :pvmList){
				String name = (String) pvmTransition.getProperty("name");
				if(StringUtils.isNotBlank(name)){
					list.add(name);
				}else{
					list.add(" ");
				}
			}
		}
		return list;
	}


	/**
	 * 查询当前任务节点流出线指定属性集合（可用于在办理任务节点操作进行驳回或通过）
	 * @param taskId
	 * @param propertyName
	 * @return
	 */
	public List getOutTransListByTaskId(String taskId,String propertyName) {
		List<String> list = new ArrayList();
		if(StringUtil.isEmpty(propertyName)){
			return list;
		}
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();//使用任务ID，查询任务对象
		String processDefinitionId = task.getProcessDefinitionId();//获取流程定义ID
		ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(processDefinitionId);//查询ProcessDefinitionEntiy对象
		String processInstanceId = task.getProcessInstanceId();//使用任务对象Task获取流程实例ID
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();//使用流程实例ID，查询正在执行的执行对象表，返回流程实例对象
		String activityId = processInstance.getActivityId();//获取当前活动的id
		ActivityImpl activityImpl = processDefinitionEntity.findActivity(activityId);//获取当前的活动
		List<PvmTransition> pvmList = activityImpl.getOutgoingTransitions();//获取当前活动完成之后连线的名称
		if(pvmList!=null && pvmList.size()>0){
			for(PvmTransition pvmTransition :pvmList){
				String name = (String) pvmTransition.getProperty(propertyName);
				if(StringUtils.isNotBlank(name)){
					list.add(name);
				} else{
					list.add(" ");
				}
			}
		}
		return list;
	}

	/**
	 * 设置Task变量（如在处理当前任务设置变量 在下一个节点中可以获取该变量）
	 * @param taskId
	 * @param map
	 * @return
	 */
	public boolean setTaskVariable(String taskId,Map<String,Object> map){
		boolean b = true;
		try {
			taskService.setVariables(taskId,map);
		}catch (Exception e){
			b= false;
			log.error("设置任务变量异常：{}",e);
		}
		return b;
	}

	/**
	 * 设置Task变量（如在处理当前任务设置变量 在下一个节点中可以获取该变量）
	 * @param taskId
	 * @param key
	 * @param value
	 * @return
	 */
	public boolean setTaskVariable(String taskId,String key,String value){
		boolean b = true;
		try {
			taskService.setVariable(taskId,key,value);
		}catch (Exception e){
			b= false;
			log.error("设置任务变量异常：{}",e);
		}
		return b;
	}

	/**
	 * 查询设置Task变量（如在处理当前任务设置变量 在下一个节点中可以获取该变量）
	 * @param taskId
	 * @return
	 */
	public Map getTaskVariable(String taskId){
		try {
			return taskService.getVariables(taskId);
		}catch (Exception e){
			log.error("查询设置任务变量异常：{}",e);
		}
		return null;
	}

	/**
	 * 查询设置Task变量（如在处理当前任务设置变量 在下一个节点中可以获取该变量）
	 * @param taskId
	 * @return
	 */
	public String getTaskVariable(String taskId,String key){
		try {
			return ""+taskService.getVariable(taskId,key);
		}catch (Exception e){
			log.error("查询设置任务变量异常：{}",e);
		}
		return null;
	}


	/**
	 * 查询业务Key
	 * @param taskId
	 * @return
	 */
	public String getBusinessKey(String taskId){
		try {
			Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
			ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
			String businessKey = pi.getBusinessKey();
			return businessKey;
		}catch (Exception e){
			log.error("查询业务Key异常：{}",e);
		}
		return null;
	}


	/**
	 * 根据bpmn节点查找节点
	 * 该方法无需流程部署
	 * @param bpmn
	 */
	public Collection<FlowElement> getFlowElementsOfTypeByBpmn(String bpmn){
		if(StringUtil.isEmpty(bpmn)){
			return new ArrayList<>();
		}
		InputStream resouceStream = new ByteArrayInputStream(bpmn.getBytes(StandardCharsets.UTF_8));
		XMLInputFactory xif = XMLInputFactory.newInstance();
		InputStreamReader in;
		XMLStreamReader xtr;
		try {
			in = new InputStreamReader(resouceStream, "UTF-8");
			xtr = xif.createXMLStreamReader(in);
			BpmnModel model = new BpmnXMLConverter().convertToBpmnModel(xtr);
			Collection<FlowElement> flowElements = model.getMainProcess().getFlowElements();
			return flowElements;
		} catch (XMLStreamException e) {
			log.error("XMLStreamException异常：{}",e);
		} catch (UnsupportedEncodingException e) {
			log.error("UnsupportedEncodingException异常：{}",e);
		}
		return new ArrayList<>();
	}

	/**
	 * 根据bpmn节点查找任务节点
	 * 该方法无需流程部署
	 * @param bpmn
	 * @return
	 */
	public List<UserTask> getUserTaskElementsByBpmn(String bpmn){
		if(StringUtil.isEmpty(bpmn)){
			return new ArrayList<>();
		}
		InputStream resouceStream = new ByteArrayInputStream(bpmn.getBytes(StandardCharsets.UTF_8));
		XMLInputFactory xif = XMLInputFactory.newInstance();
		InputStreamReader in;
		XMLStreamReader xtr;
		try {
			in = new InputStreamReader(resouceStream, "UTF-8");
			xtr = xif.createXMLStreamReader(in);
			BpmnModel model = new BpmnXMLConverter().convertToBpmnModel(xtr);
			List<UserTask> UserTaskList  = model.getMainProcess().findFlowElementsOfType(UserTask.class);
			return UserTaskList;
		} catch (XMLStreamException e) {
			log.error("XMLStreamException异常：{}",e);
		} catch (UnsupportedEncodingException e) {
			log.error("UnsupportedEncodingException异常：{}",e);
		}
		return new ArrayList<>();
	}

	/**
	 * 根据bpmn+taskDefinitionKey节点查找任务节点
	 * 该方法无需流程部署
	 * @param bpmn
	 * @return
	 */
	public UserTask getUserTask(String bpmn,String taskDefinitionKey){
		if(StringUtil.isEmpty(bpmn)){
			return null;
		}
		InputStream resouceStream = new ByteArrayInputStream(bpmn.getBytes(StandardCharsets.UTF_8));
		XMLInputFactory xif = XMLInputFactory.newInstance();
		InputStreamReader in;
		XMLStreamReader xtr;
		try {
			in = new InputStreamReader(resouceStream, "UTF-8");
			xtr = xif.createXMLStreamReader(in);
			BpmnModel model = new BpmnXMLConverter().convertToBpmnModel(xtr);
			List<UserTask> userTaskList  = model.getMainProcess().findFlowElementsOfType(UserTask.class);
			for(UserTask userTask: userTaskList){
				if(userTask.getId().equals(taskDefinitionKey)){
					return userTask;
				}
			}
		} catch (XMLStreamException e) {
			log.error("XMLStreamException异常：{}",e);
		} catch (UnsupportedEncodingException e) {
			log.error("UnsupportedEncodingException异常：{}",e);
		}
		return null;
	}

	/**
	 * 根据bpmn节点查找任务节点
	 * 该方法无需流程部署
	 * @param bpmn
	 * @return
	 */
	public List<EndEvent> getEventElementsByBpmn(String bpmn){
		if(StringUtil.isEmpty(bpmn)){
			return new ArrayList<>();
		}
		InputStream resouceStream = new ByteArrayInputStream(bpmn.getBytes(StandardCharsets.UTF_8));
		XMLInputFactory xif = XMLInputFactory.newInstance();
		InputStreamReader in;
		XMLStreamReader xtr;
		try {
			in = new InputStreamReader(resouceStream, "UTF-8");
			xtr = xif.createXMLStreamReader(in);
			BpmnModel model = new BpmnXMLConverter().convertToBpmnModel(xtr);
			List<EndEvent> endEvents  = model.getMainProcess().findFlowElementsOfType(EndEvent.class);
			return endEvents;
		} catch (XMLStreamException e) {
			log.error("XMLStreamException异常：{}",e);
		} catch (UnsupportedEncodingException e) {
			log.error("UnsupportedEncodingException异常：{}",e);
		}
		return new ArrayList<>();
	}


	/**
	 * 根据流程定义查找所有节点
	 *  该方法必须是流程已部署完成
	 * @param processDefinitionId
	 */
	public Collection<FlowElement> getFlowElementsOfType(String processDefinitionId){
		BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
		Process process = bpmnModel.getProcesses().get(0);
		Collection<FlowElement> flowElements = process.getFlowElements();//所有节点
		return flowElements;
	}

	/**
	 * 根据流程定义+类 查找所有节点
	 * 该方法必须是流程已部署完成
	 * @param processDefinitionId
	 */
	public List<FlowElement> getFlowElementsOfType(String processDefinitionId,Class classz){
		BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
		Process process = bpmnModel.getProcesses().get(0);
		List<FlowElement> flowElements = process.findFlowElementsOfType(classz);
		return flowElements;
	}


	/**
	 * 根据流程定义查找所有任务节点
	 * 该方法必须是流程已部署完成
	 * @param processDefinitionId
	 */
	public List<UserTask> getUserTaskElements(String processDefinitionId){
		BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
		Process process = bpmnModel.getProcesses().get(0);
		List<UserTask> UserTaskList = process.findFlowElementsOfType(UserTask.class);
		return UserTaskList;
	}

	/**
	 * 根据流程实例查找当前的所有执行实例ExecutionEntity集合
	 * @param processInstanceId
	 * @return
	 */
	public List<ExecutionEntity> getExecutionEntitiesByProcessInstanceId(String processInstanceId){
		ExecutionEntityManager executionEntityManager = Context.getCommandContext().getExecutionEntityManager();
		List<ExecutionEntity> executionEntities = executionEntityManager.findChildExecutionsByProcessInstanceId(processInstanceId);
		return executionEntities;
	}


	/**
	 * 根据流程实例查找当前的所有执行实例Execution集合
	 * @param processInstanceId
	 * @return
	 */
	public List<Execution> getExecutionByProcessInstanceId(String processInstanceId){
		List<Execution> executions = runtimeService.createExecutionQuery().processInstanceId(processInstanceId).list();
		return executions;
	}


	/**
	 * 自由跳转
	 * @param lcReceiveNParam
	 * @return
	 */
	public BaseResult jump(LcReceiveNParam lcReceiveNParam){
		JumpTaskCmd jumpTaskCmd = new JumpTaskCmd(lcReceiveNParam.getTaskId(), lcReceiveNParam.getActivityId(),lcReceiveNParam.getVariables(),lcReceiveNParam.isEndAllActivityInstances());
		try {
			HistoricTaskInstance historicTaskInstance = getTaskById(lcReceiveNParam.getTaskId());
			if(null == historicTaskInstance){
				log.warn("未能找到流程实例，{}"+lcReceiveNParam);
				throw new ExceptionUtil("未能找到流程实例，任务id："+lcReceiveNParam.getTaskId());
			}
			actRunVariableService.delActRunVariableByInstanceId(historicTaskInstance.getProcessInstanceId());//将变量数据删除，否则会签失效
			((RuntimeServiceImpl)runtimeService).getCommandExecutor().execute(jumpTaskCmd);
		}catch (Exception e){
            throw new ExceptionUtil("操作异常："+e.getMessage());
		}
		return new BaseResult("跳转成功",true);
	}

	/**
	 *
	 */
	public class JumpTaskCmd implements Command<ExecutionEntity> {
		protected String taskId;//当前任务id
		protected String targetActivityId;//目标节点
		protected Map<String, Object> variables;//变量
		protected LcNodeAttribute lcNodeAttribute;//当前节点规则属性
		protected LcNodeAttribute targetLcNodeAttribute;//目标节点规则属性
		protected boolean endAllActivityInstances = false;//结束所有活动实例 默认false (表示当执行跳转规则的时候 结束其它所有正在运行的实例)
		@Override
		public ExecutionEntity execute(CommandContext commandContext) {
			if(StringUtil.isEmpty(taskId)){
				throw new ExceptionUtil("任务编号不存在");
			}
			Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
			if(null == task){
				throw new ExceptionUtil("当前任务不存在");
			}
			if(task.isSuspended()){
				log.warn("当前任务实例已挂起，不能操作，{}",taskId);
				throw new ExceptionUtil("当前任务实例已挂起，不能操作");
			}
			ActivityImpl currentActivity = getActivityImpl(taskId);//当前任务查找当前节点
			if(null == currentActivity){
				throw new ExceptionUtil("未能找到当前节点");
			}
			if(StringUtil.isEmpty(targetActivityId)){
				throw new ExceptionUtil("目标节点编号为空");
			}
			LcReceiveParam lcReceiveParam = new LcReceiveParam();
			lcReceiveParam.setActivityId(targetActivityId);
			lcReceiveParam.setProcessInstanceId(task.getProcessInstanceId());
			ActivityImpl targetActivity = getActivityImpl(lcReceiveParam);
			String executionId = task.getExecutionId();//执行实例id
			if(StringUtil.isEmpty(executionId)){
				throw new ExceptionUtil("当前任务对应的执行实例id未能找到");
			}
			if(null == targetActivity){
				throw new ExceptionUtil("目标节点对象不存在");
			}
			String processInstanceId = task.getProcessInstanceId();//流程实例id
			if(StringUtil.isEmpty(processInstanceId)){
				throw new ExceptionUtil("未能找到流程实例id");
			}

			ExecutionEntityManager executionEntityManager = Context.getCommandContext().getExecutionEntityManager();

			//////////////方法一解决并行网关实例 并行 串行 开始//////////////////
			TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
			TaskEntity taskEntity = taskEntityManager.findTaskById(taskId);

			ExecutionEntity parentExecutionEntity = taskEntity.getProcessInstance();//当前任务TaskId对应的执行根实例（一级目录）
			if(endAllActivityInstances){//需要强制终止其它任务
				//parentExecutionEntity采用的是一级目录
			}else{//普通流转
				//则根据类型 重新赋予parentExecutionEntity
				if(currentActivity.getActivityBehavior() instanceof SequentialMultiInstanceBehavior) {
					parentExecutionEntity = taskEntity.getExecution().getParent();
				}else if(currentActivity.getActivityBehavior() instanceof ParallelMultiInstanceBehavior) {
					parentExecutionEntity = taskEntity.getExecution().getParent().getParent();
				}else {
					parentExecutionEntity = taskEntity.getExecution();
				}
			}
			// 设置流程变量
			parentExecutionEntity.setVariables(variables);
			parentExecutionEntity.setExecutions(null);
			parentExecutionEntity.setActivity(currentActivity);
			parentExecutionEntity.setEventSource(currentActivity);
			parentExecutionEntity.setActive(true);
			// 触发全局事件转发器TASK_COMPLETED事件
			if (Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
				Context.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(ActivitiEventBuilder
						.createEntityWithVariablesEvent(ActivitiEventType.TASK_COMPLETED, this, variables, false));
			}

			if(endAllActivityInstances) {//需要强制终止其它任务
				Iterator<TaskEntity> localIterator = Context.getCommandContext().getTaskEntityManager().findTasksByProcessInstanceId(processInstanceId).iterator();
				//删除所有任务项
				while (localIterator.hasNext()) {
					TaskEntity entity = (TaskEntity) localIterator.next();
					log.info("所删除的任务项TaskId:" + entity.getId());
					if(taskId.equals(entity.getId())) {
						taskEntity.fireEvent("complete");// 触发任务监听
						taskEntityManager.deleteTask(entity, "completed", false);// 删除任务的原因
					}else {
						taskEntityManager.deleteTask(entity, "deleted", false);// 删除任务的原因
					}
				}
			}else{
				// 删除任务
				List<ExecutionEntity> childExecutionEntityList = parentExecutionEntity.getExecutions();
				if(childExecutionEntityList.size() == 0) {//普通任务
					taskEntityManager.deleteTask(taskEntity, TaskEntity.DELETE_REASON_COMPLETED, false);
				}
				for(ExecutionEntity childExecutionEntity : childExecutionEntityList) {//会签任务
					List<ExecutionEntity> childExecutionEntityList1 = childExecutionEntity.getExecutions();
					if(childExecutionEntityList1.size() == 0) {//串行多实例任务处理
						List<TaskEntity> taskList = childExecutionEntity.getTasks();
						for(TaskEntity entity : taskList) {
							entity.fireEvent(TaskListener.EVENTNAME_COMPLETE);
							taskEntityManager.deleteTask(entity, TaskEntity.DELETE_REASON_COMPLETED, false);
						}
					}else {//并行多实例任务处理
						for(ExecutionEntity childExecutionEntity1 : childExecutionEntityList1) {
							List<TaskEntity> taskList1 = childExecutionEntity1.getTasks();
							for(TaskEntity entity : taskList1) {
								entity.fireEvent(TaskListener.EVENTNAME_COMPLETE);
								taskEntityManager.deleteTask(entity, TaskEntity.DELETE_REASON_COMPLETED, false);
							}
						}
					}
				}
			}
			//删除执行实例
			if(endAllActivityInstances) {//需要强制终止其它任务
				//强制类型则需要删除所有执行实例 需要递归删除
				recursionRemove(parentExecutionEntity,executionEntityManager);
			}else{//普通删除
				//普通类型 则通过找到三级目录即可
				List<ExecutionEntity> childExecutionList = executionEntityManager.findChildExecutionsByParentExecutionId(parentExecutionEntity.getId());
				for(ExecutionEntity executionEntityChild : childExecutionList) {
					List<ExecutionEntity> childExecutionList1 = executionEntityManager.findChildExecutionsByParentExecutionId(executionEntityChild.getId());
					for(ExecutionEntity executionEntityChild1 : childExecutionList1) {
						executionEntityChild1.remove();
						Context.getCommandContext().getHistoryManager().recordActivityEnd(executionEntityChild1);
					}
					executionEntityChild.remove();
					Context.getCommandContext().getHistoryManager().recordActivityEnd(executionEntityChild);
				}
			}
			commandContext.getIdentityLinkEntityManager().deleteIdentityLinksByProcInstance(processInstanceId);
			parentExecutionEntity.removeVariable("nrOfInstances");
			parentExecutionEntity.removeVariable("nrOfActiveInstances");
			parentExecutionEntity.removeVariable("nrOfCompletedInstances");
			parentExecutionEntity.removeVariable("loopCounter");
			parentExecutionEntity.removeVariables();
			parentExecutionEntity.setVariables(variables);//重新设置变量
			targetActivity.setVariables(variables);//设置目标节点变量（如会签节点审批人可以带上）
			parentExecutionEntity.setActivity(targetActivity);
			parentExecutionEntity.performOperation(AtomicOperation.TRANSITION_CREATE_SCOPE);
			return parentExecutionEntity;
			//////////////方法一解决并行网关实例 并行 串行 结束//////////////////


			/*方法二 比较暴力 并行任务都会被强制结束
			ExecutionEntityManager executionEntityManager = Context.getCommandContext().getExecutionEntityManager();
			ExecutionEntity executionEntity = executionEntityManager.findExecutionById(executionId);
			//查找根路径
			String id = null;
			if (executionEntity.getParent() != null) {
				executionEntity = executionEntity.getParent();
				if (executionEntity.getParent() != null) {
					executionEntity = executionEntity.getParent();
					id = executionEntity.getId();
				}
				id = executionEntity.getId();
			}

			//设置相关变量
			executionEntity.setVariables(variables);
//			executionEntity.setExecutions(null);
			executionEntity.setEventSource(currentActivity);
			executionEntity.setActivity(currentActivity);
			// 根据executionId 获取Task
			Iterator<TaskEntity> localIterator = Context.getCommandContext().getTaskEntityManager().findTasksByProcessInstanceId(processInstanceId).iterator();
			//删除无用的工作项
			while (localIterator.hasNext()) {
				TaskEntity entity = (TaskEntity) localIterator.next();
				log.info("无用的TaskId:" + entity.getId());
				if(taskId.equals(entity.getId())) {
					// 触发任务监听
					taskEntity.fireEvent("complete");
					// 删除任务的原因
					Context.getCommandContext().getTaskEntityManager().deleteTask(entity, "completed", false);
				}else {
					// 删除任务的原因
					Context.getCommandContext().getTaskEntityManager().deleteTask(entity, "deleted", false);
				}
			}

//			//删除相关执行子路径，只保留根执行路径
//			List<ExecutionEntity> executionEntities = executionEntityManager.findChildExecutionsByParentExecutionId(processInstanceId);
//			for (ExecutionEntity executionEntity2 : executionEntities) {//操作子路径
//				List<ExecutionEntity> executionChildEntities = executionEntityManager.findChildExecutionsByParentExecutionId(executionEntity2.getId());
//				for (ExecutionEntity executionEntity3 : executionChildEntities) {
//					executionEntity3.remove();
//					log.info(executionEntity3.getId());
//					Context.getCommandContext().getHistoryManager().recordActivityEnd(executionEntity3);
//				}
//				executionEntity2.remove();
//				Context.getCommandContext().getHistoryManager().recordActivityEnd(executionEntity2);
//				log.info( "findExecutionById：{}",executionEntity2);
//			}

			//删除相关执行子路径，只保留根执行路径
			List<ExecutionEntity> executionEntities = executionEntityManager.findChildExecutionsByParentExecutionId(processInstanceId);
			ExecutionDTO executionDTO = new ExecutionDTO();
			executionDTO.setExecutionEntities(executionEntities);
			recursion(executionEntityManager,executionDTO);

			for (ExecutionEntity executionEntity2 : executionEntities) {//操作子路径
				List<ExecutionEntity> executionChildEntities = executionEntityManager.findChildExecutionsByParentExecutionId(executionEntity2.getId());
				for (ExecutionEntity executionEntity3 : executionChildEntities) {
					List<ExecutionEntity> executionChildChildEntities = executionEntityManager.findChildExecutionsByParentExecutionId(executionEntity3.getId());
					for(ExecutionEntity executionEntity4 :executionChildChildEntities){
						log.info(executionEntity4.getId());
					}
					executionEntity3.remove();
					log.info(executionEntity3.getId());
					Context.getCommandContext().getHistoryManager().recordActivityEnd(executionEntity3);
				}
				executionEntity2.remove();
				Context.getCommandContext().getHistoryManager().recordActivityEnd(executionEntity2);
				log.info( "findExecutionById：{}",executionEntity2);
			}

			commandContext.getIdentityLinkEntityManager().deleteIdentityLinksByProcInstance(processInstanceId);
			executionEntity.setActive(true);//要激活提交路径
//			executionEntity.removeVariables();
//			executionEntity.removeVariablesLocal();
			executionEntity.removeVariable("nrOfInstances");//去掉无用的变量，不去掉，会导致很多莫名奇妙的问题
			executionEntity.removeVariable("nrOfActiveInstances");//去掉无用的变量，不去掉，会导致很多莫名奇妙的问题
			executionEntity.removeVariable("nrOfCompletedInstances");//去掉无用的变量，不去掉，会导致很多莫名奇妙的问题
			executionEntity.removeVariable("loopCounter");//去掉无用的变量，不去掉，会导致很多莫名奇妙的问题
			this.execute(executionEntity);//触发事件监听器
			InterpretableExecution propagatingExecution = null;
			if (targetActivity.isScope()) {
				propagatingExecution = (InterpretableExecution) executionEntity.createExecution();
				executionEntity.setTransition(null);
				executionEntity.setActivity(null);
				executionEntity.setActive(false);
				propagatingExecution.initialize();
			} else {
				propagatingExecution = executionEntity;
			}
			targetActivity.setVariables(variables);//设置目标节点变量（如会签节点审批人可以带上）
			propagatingExecution.executeActivity(targetActivity);
			return null;*/
		}
		protected ScopeImpl getScope(InterpretableExecution execution) {
			return (ScopeImpl) execution.getActivity();
		}

		/**
		 * 触发事件监听器
		 * @param execution
		 */
		public void execute(InterpretableExecution execution) {
			ScopeImpl scope = getScope(execution);
			List<ExecutionListener> exectionListeners = scope.getExecutionListeners(getEventName());
			for (ExecutionListener listener : exectionListeners) {
				execution.setEventName(getEventName());
				execution.setEventSource(scope);
				try {
					listener.notify(execution);
				} catch (RuntimeException e) {
					throw e;
				} catch (Exception e) {
					throw new PvmException("couldn't execute event listener : " + e.getMessage(), e);
				}

			}
		}
		protected String getEventName() {
			return org.activiti.engine.impl.pvm.PvmEvent.EVENTNAME_END;
		}

		/**
		 * 递归移除
		 * @param executionEntity
		 * @param executionEntityManager
		 */
		public void recursionRemove(ExecutionEntity executionEntity,ExecutionEntityManager executionEntityManager){
			List<ExecutionEntity> executionEntities = executionEntityManager.findChildExecutionsByParentExecutionId(executionEntity.getId());
			for(ExecutionEntity entity : executionEntities) {
				List<ExecutionEntity> childExecutionList = executionEntityManager.findChildExecutionsByParentExecutionId(entity.getId());
				if(!CollectionUtil.isEmpty(childExecutionList)){
					recursionRemove(entity,executionEntityManager);
				}
				entity.remove();
				Context.getCommandContext().getHistoryManager().recordActivityEnd(entity);
			}
		}

		/**
		 * 构造参数
		 * @param taskId 当前任务id
		 * @param targetActivityId 目标节点
		 * @param variables 变量
		 */
		public JumpTaskCmd(String taskId,String targetActivityId, Map<String, Object> variables) {
			this.taskId=taskId;
			this.targetActivityId = targetActivityId;
			this.variables = variables;
		}

		/**
		 * 构造参数
		 * @param taskId 当前任务id
		 * @param targetActivityId 目标节点
		 * @param variables 变量
		 * @param endAllActivityInstances 结束当前所有活动实例
		 */
		public JumpTaskCmd(String taskId,String targetActivityId, Map<String, Object> variables,boolean endAllActivityInstances) {
			this.taskId=taskId;
			this.targetActivityId = targetActivityId;
			this.variables = variables;
			this.endAllActivityInstances = endAllActivityInstances;
		}

		/**
		 * 构造参数
		 * @param taskId 当前任务id
		 * @param targetActivityId 目标节点
		 * @param variables 变量
		 * @param lcNodeAttribute 当前节点属性规则
		 */
		public JumpTaskCmd(String taskId,String targetActivityId, Map<String, Object> variables,LcNodeAttribute lcNodeAttribute) {
			this.taskId=taskId;
			this.targetActivityId = targetActivityId;
			this.variables = variables;
			this.lcNodeAttribute = lcNodeAttribute;
		}

		/**
		 * 构造参数
		 * @param taskId 当前任务id
		 * @param targetActivityId 目标节点
		 * @param variables 变量
		 * @param lcNodeAttribute 当前节点属性规则
		 * @param targetLcNodeAttribute 目标节点属性规则
		 */
		public JumpTaskCmd(String taskId,String targetActivityId, Map<String, Object> variables,LcNodeAttribute lcNodeAttribute,LcNodeAttribute targetLcNodeAttribute) {
			this.taskId=taskId;
			this.targetActivityId = targetActivityId;
			this.variables = variables;
			this.lcNodeAttribute = lcNodeAttribute;
			this.targetLcNodeAttribute = targetLcNodeAttribute;
		}
	}

	/**
	 * 查询原节点审批人（会签任务不在该地方获取，采用自定义表存储lc_his_mutil表）
	 * @param lcReceiveNParam
	 * @return
	 */
	public List<HistoricActivityInstance> getHisAcitivitis(LcReceiveNParam lcReceiveNParam){
		if(StringUtil.isEmpty(lcReceiveNParam.getProcessInstanceId())){
			return new ArrayList<>();
		}
		if(StringUtil.isEmpty(lcReceiveNParam.getActivityId())){
			return new ArrayList<>();
		}
		HistoricActivityInstanceQuery historicActivityInstanceQuery = getHistoryService()
				.createHistoricActivityInstanceQuery(); // 创建历史活动实例查询
		//指定流程定义Id，只查询某个业务流程的实例
		historicActivityInstanceQuery.orderByHistoricActivityInstanceEndTime().desc();
		historicActivityInstanceQuery.processInstanceId(String.valueOf(lcReceiveNParam.getProcessInstanceId()));
		historicActivityInstanceQuery.activityId(lcReceiveNParam.getActivityId());
		List<HistoricActivityInstance> historicActivityInstances = historicActivityInstanceQuery.list();
		return historicActivityInstances;
	}

	/**
	 * 根据当前任务查找流程图上配置的上级节点（注意仅为流程图上配置走向节点）
	 * @param lcReceiveNParam
	 * @return
	 */
	public List<UserTask> previousNode(LcReceiveNParam lcReceiveNParam){
		if(null == lcReceiveNParam){
			log.info("lcReceiveParam为空！",lcReceiveNParam);
			return null;
		}
		if(StringUtil.isEmpty(lcReceiveNParam.getTaskId())){
			log.info("当前任务id为空！",lcReceiveNParam);
			return null;
		}
		HistoricTaskInstance historicTaskInstance = getTaskById(lcReceiveNParam.getTaskId());
		if(null == historicTaskInstance){
			log.info("当前任务对应的流程实例不存在！",lcReceiveNParam);
			return null;
		}
		String taskDefinitionKey= historicTaskInstance.getTaskDefinitionKey();
		String processDefinitionId = historicTaskInstance.getProcessDefinitionId();
		if(StringUtil.isEmpty(processDefinitionId)){
			log.info("当前任务未能找到流程定义id！",lcReceiveNParam);
			return null;
		}
		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
		if(null == processDefinition){
			log.info("未能找到流程定义对象！",lcReceiveNParam);
			return null;
		}
		BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
		if(null == bpmnModel){
			log.info("bpmnModel为空！",lcReceiveNParam);
			return null;
		}
		List<UserTask> userTasks = new ArrayList<>();

		List<Process> processes = bpmnModel.getProcesses();
		if(CollectionUtil.isEmpty(processes)){
			log.info("bpmnModel下未能找到流程processes！",lcReceiveNParam);
			return null;
		}
		Process process = processes.get(0);
		Collection<FlowElement> flowElements = process.getFlowElements();
		if(CollectionUtil.isEmpty(flowElements)){
			log.info("未能找到flowElements！",lcReceiveNParam);
			return null;
		}
		recursionGetPreviousNodeUserTask(bpmnModel,taskDefinitionKey,userTasks,flowElements);
		log.info("上个节点：{}",userTasks.size());
		return userTasks;
	}


	/**
	 * 递归寻找上一个节点
	 * @param bpmnModel
	 * @param elementKey
	 * @param userTasks
	 * @param flowElements
	 */
	private void recursionGetPreviousNodeUserTask( BpmnModel bpmnModel, String elementKey, List<UserTask> userTasks,Collection<FlowElement> flowElements) {
		//获取当前节点信息
		FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(elementKey);
		//获取当前节点输出连线
		List<SequenceFlow> incomingFlows = flowNode.getIncomingFlows();
		//遍历输出连线
		for (SequenceFlow incomingFlow : incomingFlows) {
			//获取输出节点元素
			FlowElement sourceFlowElement = getFlowElementById(incomingFlow.getSourceRef(),flowElements);
			if(null == sourceFlowElement){
				continue;
			}
			//排除非用户任务接点
			if (sourceFlowElement instanceof UserTask) {
				//判断输出节点的el表达式
				//true 获取输出节点名称
				userTasks.add((UserTask) sourceFlowElement);
				break;
			} else {
				recursionGetPreviousNodeUserTask(bpmnModel, sourceFlowElement.getId(), userTasks,flowElements);
			}
		}
	}

	/**
	 * 查询节点
	 * @param id
	 * @param flowElements
	 * @return
	 */
	private FlowElement getFlowElementById(String id,Collection<FlowElement> flowElements){
		for(FlowElement flowElement:flowElements){
			if(id.equals(flowElement.getId())){
				return flowElement;
			}
		}
		return null;
	}

	/**
	 * TaskEntityCmd 命令类
	 */
	public class TaskEntityCmd implements Command<TaskEntity> {
		protected String taskId;//当前任务id
		protected String targetActivityId;//目标节点
		protected Map<String, Object> variables;//变量
		protected LcNodeAttribute lcNodeAttribute;//当前节点规则属性
		protected LcNodeAttribute targetLcNodeAttribute;//目标节点规则属性
		protected boolean endAllActivityInstances = false;//结束所有活动实例 默认false (表示当执行跳转规则的时候 结束其它所有正在运行的实例)
		@Override
		public TaskEntity execute(CommandContext commandContext) {
			if(StringUtil.isEmpty(taskId)){
				throw new ExceptionUtil("任务编号不存在");
			}
			Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
			if(null == task){
				throw new ExceptionUtil("当前任务不存在");
			}
			TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
			TaskEntity taskEntity = taskEntityManager.findTaskById(taskId);
			return taskEntity;
		}
		protected ScopeImpl getScope(InterpretableExecution execution) {
			return (ScopeImpl) execution.getActivity();
		}

		/**
		 * 触发事件监听器
		 * @param execution
		 */
		public void execute(InterpretableExecution execution) {
			ScopeImpl scope = getScope(execution);
			List<ExecutionListener> exectionListeners = scope.getExecutionListeners(getEventName());
			for (ExecutionListener listener : exectionListeners) {
				execution.setEventName(getEventName());
				execution.setEventSource(scope);
				try {
					listener.notify(execution);
				} catch (RuntimeException e) {
					throw e;
				} catch (Exception e) {
					throw new PvmException("couldn't execute event listener : " + e.getMessage(), e);
				}

			}
		}
		protected String getEventName() {
			return org.activiti.engine.impl.pvm.PvmEvent.EVENTNAME_END;
		}

		/**
		 * 构造参数
		 * @param taskId 当前任务id
		 * @param targetActivityId 目标节点
		 * @param variables 变量
		 */
		public TaskEntityCmd(String taskId,String targetActivityId, Map<String, Object> variables) {
			this.taskId=taskId;
			this.targetActivityId = targetActivityId;
			this.variables = variables;
		}

		/**
		 * 构造参数
		 * @param taskId 当前任务id
		 * @param targetActivityId 目标节点
		 * @param variables 变量
		 * @param endAllActivityInstances 结束当前所有活动实例
		 */
		public TaskEntityCmd(String taskId,String targetActivityId, Map<String, Object> variables,boolean endAllActivityInstances) {
			this.taskId=taskId;
			this.targetActivityId = targetActivityId;
			this.variables = variables;
			this.endAllActivityInstances = endAllActivityInstances;
		}

		/**
		 * 构造参数
		 * @param taskId 当前任务id
		 * @param targetActivityId 目标节点
		 * @param variables 变量
		 * @param lcNodeAttribute 当前节点属性规则
		 */
		public TaskEntityCmd(String taskId,String targetActivityId, Map<String, Object> variables,LcNodeAttribute lcNodeAttribute) {
			this.taskId=taskId;
			this.targetActivityId = targetActivityId;
			this.variables = variables;
			this.lcNodeAttribute = lcNodeAttribute;
		}

		/**
		 * 构造参数
		 * @param taskId 当前任务id
		 * @param targetActivityId 目标节点
		 * @param variables 变量
		 * @param lcNodeAttribute 当前节点属性规则
		 * @param targetLcNodeAttribute 目标节点属性规则
		 */
		public TaskEntityCmd(String taskId,String targetActivityId, Map<String, Object> variables,LcNodeAttribute lcNodeAttribute,LcNodeAttribute targetLcNodeAttribute) {
			this.taskId=taskId;
			this.targetActivityId = targetActivityId;
			this.variables = variables;
			this.lcNodeAttribute = lcNodeAttribute;
			this.targetLcNodeAttribute = targetLcNodeAttribute;
		}
	}


	/**
	 * ExecutionEntityCmd 命令类
	 */
	public class ExecutionEntityCmd implements Command<ExecutionEntity> {
		protected String taskId;//当前任务id
		protected String targetActivityId;//目标节点
		protected Map<String, Object> variables;//变量
		protected LcNodeAttribute lcNodeAttribute;//当前节点规则属性
		protected LcNodeAttribute targetLcNodeAttribute;//目标节点规则属性
		protected boolean endAllActivityInstances = false;//结束所有活动实例 默认false (表示当执行跳转规则的时候 结束其它所有正在运行的实例)
		@Override
		public ExecutionEntity execute(CommandContext commandContext) {
			if(StringUtil.isEmpty(taskId)){
				throw new ExceptionUtil("任务编号不存在");
			}
			Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
			if(null == task){
				throw new ExceptionUtil("当前任务不存在");
			}
			TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
			TaskEntity taskEntity = taskEntityManager.findTaskById(taskId);
			ExecutionEntity executionEntity = taskEntity.getProcessInstance();//当前任务TaskId对应的执行根实例（一级目录）
			return executionEntity;
		}
		protected ScopeImpl getScope(InterpretableExecution execution) {
			return (ScopeImpl) execution.getActivity();
		}

		/**
		 * 触发事件监听器
		 * @param execution
		 */
		public void execute(InterpretableExecution execution) {
			ScopeImpl scope = getScope(execution);
			List<ExecutionListener> exectionListeners = scope.getExecutionListeners(getEventName());
			for (ExecutionListener listener : exectionListeners) {
				execution.setEventName(getEventName());
				execution.setEventSource(scope);
				try {
					listener.notify(execution);
				} catch (RuntimeException e) {
					throw e;
				} catch (Exception e) {
					throw new PvmException("couldn't execute event listener : " + e.getMessage(), e);
				}

			}
		}
		protected String getEventName() {
			return org.activiti.engine.impl.pvm.PvmEvent.EVENTNAME_END;
		}

		/**
		 * 构造参数
		 * @param taskId 当前任务id
		 * @param targetActivityId 目标节点
		 * @param variables 变量
		 */
		public ExecutionEntityCmd(String taskId,String targetActivityId, Map<String, Object> variables) {
			this.taskId=taskId;
			this.targetActivityId = targetActivityId;
			this.variables = variables;
		}

		/**
		 * 构造参数
		 * @param taskId 当前任务id
		 * @param targetActivityId 目标节点
		 * @param variables 变量
		 * @param endAllActivityInstances 结束当前所有活动实例
		 */
		public ExecutionEntityCmd(String taskId,String targetActivityId, Map<String, Object> variables,boolean endAllActivityInstances) {
			this.taskId=taskId;
			this.targetActivityId = targetActivityId;
			this.variables = variables;
			this.endAllActivityInstances = endAllActivityInstances;
		}

		/**
		 * 构造参数
		 * @param taskId 当前任务id
		 * @param targetActivityId 目标节点
		 * @param variables 变量
		 * @param lcNodeAttribute 当前节点属性规则
		 */
		public ExecutionEntityCmd(String taskId,String targetActivityId, Map<String, Object> variables,LcNodeAttribute lcNodeAttribute) {
			this.taskId=taskId;
			this.targetActivityId = targetActivityId;
			this.variables = variables;
			this.lcNodeAttribute = lcNodeAttribute;
		}

		/**
		 * 构造参数
		 * @param taskId 当前任务id
		 * @param targetActivityId 目标节点
		 * @param variables 变量
		 * @param lcNodeAttribute 当前节点属性规则
		 * @param targetLcNodeAttribute 目标节点属性规则
		 */
		public ExecutionEntityCmd(String taskId,String targetActivityId, Map<String, Object> variables,LcNodeAttribute lcNodeAttribute,LcNodeAttribute targetLcNodeAttribute) {
			this.taskId=taskId;
			this.targetActivityId = targetActivityId;
			this.variables = variables;
			this.lcNodeAttribute = lcNodeAttribute;
			this.targetLcNodeAttribute = targetLcNodeAttribute;
		}
	}


	/**
	 * LcMutilEntityCmd 命令类
	 */
	public class LcMutilEntityCmd implements Command<LcMutilEntity> {
		protected String taskId;//当前任务id
		protected String targetActivityId;//目标节点
		protected Map<String, Object> variables;//变量
		protected LcNodeAttribute lcNodeAttribute;//当前节点规则属性
		protected LcNodeAttribute targetLcNodeAttribute;//目标节点规则属性
		protected boolean endAllActivityInstances = false;//结束所有活动实例 默认false (表示当执行跳转规则的时候 结束其它所有正在运行的实例)
		@Override
		public LcMutilEntity execute(CommandContext commandContext) {
			if(StringUtil.isEmpty(taskId)){
				throw new ExceptionUtil("任务编号不存在");
			}
			Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
			if(null == task){
				throw new ExceptionUtil("当前任务不存在");
			}
			TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
			TaskEntity taskEntity = taskEntityManager.findTaskById(taskId);
			ExecutionEntity executionEntity = taskEntity.getProcessInstance();

			List<VariableInstanceEntity> variableInstanceEntityList =  ((TaskEntity)task).getQueryVariables();

			return computeMutilCount(executionEntity);
		}
		protected ScopeImpl getScope(InterpretableExecution execution) {
			return (ScopeImpl) execution.getActivity();
		}

		/**
		 * 触发事件监听器
		 * @param execution
		 */
		public void execute(InterpretableExecution execution) {
			ScopeImpl scope = getScope(execution);
			List<ExecutionListener> exectionListeners = scope.getExecutionListeners(getEventName());
			for (ExecutionListener listener : exectionListeners) {
				execution.setEventName(getEventName());
				execution.setEventSource(scope);
				try {
					listener.notify(execution);
				} catch (RuntimeException e) {
					throw e;
				} catch (Exception e) {
					throw new PvmException("couldn't execute event listener : " + e.getMessage(), e);
				}

			}
		}
		protected String getEventName() {
			return org.activiti.engine.impl.pvm.PvmEvent.EVENTNAME_END;
		}

		/**
		 * 构造参数
		 * @param taskId 当前任务id
		 * @param targetActivityId 目标节点
		 * @param variables 变量
		 */
		public LcMutilEntityCmd(String taskId,String targetActivityId, Map<String, Object> variables) {
			this.taskId=taskId;
			this.targetActivityId = targetActivityId;
			this.variables = variables;
		}

		/**
		 * 构造参数
		 * @param taskId 当前任务id
		 * @param targetActivityId 目标节点
		 * @param variables 变量
		 * @param endAllActivityInstances 结束当前所有活动实例
		 */
		public LcMutilEntityCmd(String taskId,String targetActivityId, Map<String, Object> variables,boolean endAllActivityInstances) {
			this.taskId=taskId;
			this.targetActivityId = targetActivityId;
			this.variables = variables;
			this.endAllActivityInstances = endAllActivityInstances;
		}

		/**
		 * 构造参数
		 * @param taskId 当前任务id
		 * @param targetActivityId 目标节点
		 * @param variables 变量
		 * @param lcNodeAttribute 当前节点属性规则
		 */
		public LcMutilEntityCmd(String taskId,String targetActivityId, Map<String, Object> variables,LcNodeAttribute lcNodeAttribute) {
			this.taskId=taskId;
			this.targetActivityId = targetActivityId;
			this.variables = variables;
			this.lcNodeAttribute = lcNodeAttribute;
		}

		/**
		 * 构造参数
		 * @param taskId 当前任务id
		 * @param targetActivityId 目标节点
		 * @param variables 变量
		 * @param lcNodeAttribute 当前节点属性规则
		 * @param targetLcNodeAttribute 目标节点属性规则
		 */
		public LcMutilEntityCmd(String taskId,String targetActivityId, Map<String, Object> variables,LcNodeAttribute lcNodeAttribute,LcNodeAttribute targetLcNodeAttribute) {
			this.taskId=taskId;
			this.targetActivityId = targetActivityId;
			this.variables = variables;
			this.lcNodeAttribute = lcNodeAttribute;
			this.targetLcNodeAttribute = targetLcNodeAttribute;
		}
	}


	/**
	 * 计算任务总数（注意放到lcMutilEntityCmd中使用 否则无法调用）
	 * @param executionEntity
	 */
	public LcMutilEntity computeMutilCount(ExecutionEntity executionEntity){
		if(null == executionEntity){
			return null;
		}
		int nrOfInstances = -1;
		int nrOfActiveInstances = -1;
		int nrOfCompletedInstances = -1;
//		List<VariableInstanceEntity> variableInstanceEntityList = runtimeService.createProcessInstanceQuery().processInstanceId(executionEntity.getProcessInstanceId()).includeProcessVariables().list();
		if(null != executionEntity.getVariable("nrOfInstances")){
			nrOfInstances = (Integer) executionEntity.getVariable("nrOfInstances"); //总的会签任务数量
		}
		if(null != executionEntity.getVariable("nrOfActiveInstances")){
			nrOfActiveInstances = (Integer) executionEntity.getVariable("nrOfActiveInstances"); //当前获取的会签任务数量 ---未执行的
		}
		if(null != executionEntity.getVariable("nrOfCompletedInstances")){
			nrOfCompletedInstances = (Integer) executionEntity.getVariable("nrOfCompletedInstances"); //总的会签任务数量---已执行的
		}
		LcMutilEntity lcMutilEntity = new LcMutilEntity(nrOfInstances,nrOfActiveInstances,nrOfCompletedInstances);
		log.info("当前完成会签任务后比例信息：{}",lcMutilEntity);
		return lcMutilEntity;
	}

	/**
	 *计算任务总数
	 */
	public LcMutilEntity computeMutilCount(LcReceiveParam lcReceiveParam){
		if(StringUtil.isEmpty(lcReceiveParam.getTaskId())){
			log.warn("执行computeMutilCount--任务id为空，{}",lcReceiveParam);
			return null;
		}
		String behavior = lcReceiveParam.getBehavior();
//		LcMutilEntityCmd executionEntityCmd = new LcMutilEntityCmd(lcReceiveParam.getTaskId(), lcReceiveParam.getActivityId(),lcReceiveParam.getVariables(),lcReceiveParam.isEndAllActivityInstances());
//		LcMutilEntity lcMutilEntity = ((RuntimeServiceImpl)runtimeService).getCommandExecutor().execute(executionEntityCmd);
//		if(null == lcMutilEntity){
//			log.warn("执行computeMutilCount--taskEntity为空，{}",lcReceiveParam);
//			return null;
//		}
		HistoricTaskInstance historicTaskInstance = getTaskById(lcReceiveParam.getTaskId());
		//查询当前节点的任务数量
		List<Task> taskList = taskService.createTaskQuery().taskName(historicTaskInstance.getTaskDefinitionKey()).processInstanceId(historicTaskInstance.getProcessInstanceId()).list();
		LcMutilEntity lcMutilEntity = new LcMutilEntity();
		for(Task task : taskList){

		}
		return lcMutilEntity;
	}

	/**
	 * 根据任务节点查找其所在节点的所有任务集合（会签则能显示多个记录）
	 * @param taskId
	 * @return
	 */
	public List<Task> getTaskList(String taskId){
		if(StringUtil.isEmpty(taskId)){
			return null;
		}
		HistoricTaskInstance historicTaskInstance = getTaskById(taskId);
		if(null == historicTaskInstance){
			return null;
		}
		//查询当前节点的任务数量
		List<Task> taskList = taskService.createTaskQuery().taskDefinitionKey(historicTaskInstance.getTaskDefinitionKey()).processInstanceId(historicTaskInstance.getProcessInstanceId()).list();
		return taskList;
	}


	/**
	 * 会签节点串行加签
	 */
	public class MultiInstanceSequenceCmd implements Command<LcMutilEntity> {
		private LcReceiveNParam lcReceiveNParam;
		private LcNodeAttribute lcNodeAttribute;

		public MultiInstanceSequenceCmd(LcReceiveNParam lcReceiveNParam, LcNodeAttribute lcNodeAttribute) {
			this.lcReceiveNParam = lcReceiveNParam;
			this.lcNodeAttribute = lcNodeAttribute;
		}

		public LcMutilEntity execute(CommandContext commandContext) {
			TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
			if(StringUtil.isEmpty(lcReceiveNParam.getTaskId())){
				throw new ExceptionUtil("未能获取到任务id");
			}

			TaskEntity taskEntity = taskEntityManager.findTaskById(lcReceiveNParam.getTaskId());
			ExecutionEntity executionEntity = taskEntity.getExecution();

			//多实例任务总数加一
			Integer nrOfInstances = (Integer)executionEntity.getVariable("nrOfInstances");
			Integer nrOfActiveInstances = (Integer)executionEntity.getVariable("nrOfActiveInstances");
			Integer nrOfCompletedInstances = (Integer)executionEntity.getVariable("nrOfCompletedInstances");
			nrOfInstances = nrOfInstances + 1;
			nrOfActiveInstances = nrOfActiveInstances + 1;
			executionEntity.setVariable("nrOfInstances", nrOfInstances + 1);
			executionEntity.setVariables(lcReceiveNParam.getVariables());//设置其它流程变量
			return new LcMutilEntity(taskEntity,nrOfInstances,nrOfActiveInstances,nrOfCompletedInstances);
		}
	}

	/**
	 * 会签节点并行多实例加签
	 * @param lcReceiveNParam
	 */
	public LcMutilEntity mutilParallel(LcReceiveNParam lcReceiveNParam) {
		MultiInstanceParallelCmd transferCmd = new MultiInstanceParallelCmd(lcReceiveNParam,null);
		ServiceImpl service = (ServiceImpl)getRepositoryService();
		CommandExecutor commandExecutor = service.getCommandExecutor();
		LcMutilEntity lcMutilEntity = commandExecutor.execute(transferCmd);
		return lcMutilEntity;
	}

	/**
	 * 会签节点并行多实例加签
	 */
	public class MultiInstanceParallelCmd implements Command<LcMutilEntity> {
		private LcReceiveNParam lcReceiveNParam;
		private LcNodeAttribute lcNodeAttribute;

		public MultiInstanceParallelCmd(LcReceiveNParam lcReceiveNParam, LcNodeAttribute lcNodeAttribute) {
			this.lcReceiveNParam = lcReceiveNParam;
			this.lcNodeAttribute = lcNodeAttribute;
		}

		@Override
		public LcMutilEntity execute(CommandContext commandContext) {
			if(StringUtil.isEmpty(lcReceiveNParam.getTaskId())){
				throw new ExceptionUtil("未能获取到任务id");
			}
			ProcessEngineConfigurationImpl processEngineConfiguration = commandContext.getProcessEngineConfiguration();
			TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
			TaskEntity taskEntity = taskEntityManager.findTaskById(lcReceiveNParam.getTaskId());
			ExecutionEntity executionEntity = taskEntity.getExecution();
			executionEntity.setVariables(lcReceiveNParam.getVariables());// 设置流程变量
			ExecutionEntity parentExecutionEntity = executionEntity.getParent();
			ExecutionEntity newExecutionEntity = parentExecutionEntity.createExecution();
			newExecutionEntity.setActive(true);
			newExecutionEntity.setConcurrent(true);
			newExecutionEntity.setScope(false);
			TaskEntity newTaskEntity = new TaskEntity();
			newTaskEntity.setCreateTime(new Date());
			newTaskEntity.setTaskDefinition(taskEntity.getTaskDefinition());
			newTaskEntity.setProcessDefinitionId(taskEntity.getProcessDefinitionId());
			newTaskEntity.setTaskDefinitionKey(taskEntity.getTaskDefinitionKey());
			newTaskEntity.setProcessInstanceId(taskEntity.getProcessInstanceId());
			newTaskEntity.setExecutionId(newExecutionEntity.getId());
			newTaskEntity.setAssignee(lcReceiveNParam.getMutilValue());//设置加签办理人
			newTaskEntity.setName(taskEntity.getName());
			newTaskEntity.setId(processEngineConfiguration.getIdGenerator().getNextId());
			newTaskEntity.setExecution(newExecutionEntity);
			processEngineConfiguration.getTaskService().saveTask(newTaskEntity);//持久化数据库
			Integer nrOfInstances = (Integer)executionEntity.getVariable("nrOfInstances");
			Integer nrOfActiveInstances = (Integer)executionEntity.getVariable("nrOfActiveInstances");
			Integer nrOfCompletedInstances = (Integer)executionEntity.getVariable("nrOfCompletedInstances");
			nrOfInstances = nrOfInstances + 1;
			nrOfActiveInstances = nrOfActiveInstances +1;
			executionEntity.setVariable("nrOfInstances", nrOfInstances);
			executionEntity.setVariable("nrOfActiveInstances", nrOfActiveInstances);
			newExecutionEntity.setVariableLocal("loopCounter", nrOfInstances);
			return new LcMutilEntity(newTaskEntity,nrOfInstances,nrOfActiveInstances,nrOfCompletedInstances);
		}
	}

	/**
	 * 会签节点转办人
	 * @param lcReceiveNParam
	 */
	public void mutilTransfer(LcReceiveNParam lcReceiveNParam) {
		MutilTransferCmd transferCmd = new MutilTransferCmd(lcReceiveNParam,null);
		ServiceImpl service = (ServiceImpl)getRepositoryService();
		CommandExecutor commandExecutor = service.getCommandExecutor();
		commandExecutor.execute(transferCmd);
	}

	/**
	 * 会签节点转办人设置命令
	 */
	public class MutilTransferCmd implements Command<LcMutilEntity> {
		private LcReceiveNParam lcReceiveNParam;
		private LcNodeAttribute lcNodeAttribute;

		public MutilTransferCmd(LcReceiveNParam lcReceiveNParam, LcNodeAttribute lcNodeAttribute) {
			this.lcReceiveNParam = lcReceiveNParam;
			this.lcNodeAttribute = lcNodeAttribute;
		}
		@Override
		public LcMutilEntity execute(CommandContext commandContext) {
			if(StringUtil.isEmpty(lcReceiveNParam.getTaskId())){
				throw new ExceptionUtil("未能获取到任务id");
			}
			if(StringUtil.isEmpty(lcReceiveNParam.getMutilExpression())){
				throw new ExceptionUtil("未能获取到会签节点处理人表达式");
			}
			if(StringUtil.isEmpty(lcReceiveNParam.getMutilValue())){
				throw new ExceptionUtil("未能获取到会签节点处理人");
			}
			ProcessEngineConfigurationImpl processEngineConfiguration = commandContext.getProcessEngineConfiguration();
			TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
			TaskEntity taskEntity = taskEntityManager.findTaskById(lcReceiveNParam.getTaskId());
			ExecutionEntity executionEntity = taskEntity.getExecution();
			String processDefinitionId = executionEntity.getProcessDefinitionId();
			ProcessDefinitionEntity processDefinitionEntity = Context.getProcessEngineConfiguration().getDeploymentManager().findDeployedProcessDefinitionById(processDefinitionId);
			ActivityImpl curActivityImpl = processDefinitionEntity.findActivity(taskEntity.getName());
			List<String> assigneeList = (List<String>) executionEntity.getVariable(lcReceiveNParam.getMutilExpression());//原来节点的审批人
			if (curActivityImpl.getActivityBehavior() instanceof SequentialMultiInstanceBehavior) {
				Integer nrOfInstances = (Integer) executionEntity.getVariable("nrOfInstances");
				Integer loopCounter = (Integer) executionEntity.getVariable("loopCounter");
				executionEntity.setVariableLocal("nrOfInstances", nrOfInstances + 1);
				List<String> newAssigneeList = new ArrayList<String>();//定义新审批人
				int i=0;
				for(; i<loopCounter + 1; i++) {
					newAssigneeList.add(assigneeList.get(i));
				}
				newAssigneeList.add(lcReceiveNParam.getMutilValue());//存放新的人
				for(; i<assigneeList.size(); i++) {
					newAssigneeList.add(assigneeList.get(i));
				}
				newAssigneeList.addAll(assigneeList);
				executionEntity.setVariable(lcReceiveNParam.getMutilExpression(), newAssigneeList);
			} else {
				ExecutionEntity parentExecutionEntity = executionEntity.getParent();
				ExecutionEntity newExecutionEntity = parentExecutionEntity.createExecution();
				newExecutionEntity.setActive(true);
				newExecutionEntity.setConcurrent(true);
				newExecutionEntity.setScope(false);
				TaskEntity newTaskEntity = new TaskEntity();
				newTaskEntity.setCreateTime(new Date());
				newTaskEntity.setTaskDefinition(taskEntity.getTaskDefinition());
				newTaskEntity.setProcessDefinitionId(taskEntity.getProcessDefinitionId());
				newTaskEntity.setTaskDefinitionKey(taskEntity.getTaskDefinitionKey());
				newTaskEntity.setProcessInstanceId(taskEntity.getProcessInstanceId());
				newTaskEntity.setExecutionId(newExecutionEntity.getId());
				newTaskEntity.setName(taskEntity.getName());
				newTaskEntity.setId(processEngineConfiguration.getIdGenerator().getNextId());
				newTaskEntity.setExecution(newExecutionEntity);
				newTaskEntity.setAssignee(lcReceiveNParam.getMutilValue());
				taskService.saveTask(newTaskEntity);//保存任务持久至数据库

				Integer nrOfInstances = (Integer) executionEntity.getVariable("nrOfInstances");
				Integer nrOfActiveInstances = (Integer) executionEntity.getVariable("nrOfActiveInstances");
				Integer nrOfCompletedInstances = (Integer)executionEntity.getVariable("nrOfCompletedInstances");
				nrOfInstances = nrOfInstances + 1;
				nrOfActiveInstances = nrOfActiveInstances +1;
				executionEntity.setVariable("nrOfInstances", nrOfInstances);
				executionEntity.setVariable("nrOfActiveInstances", nrOfActiveInstances);
				newExecutionEntity.setVariableLocal("loopCounter", nrOfInstances);
				return new LcMutilEntity(newTaskEntity,nrOfInstances,nrOfActiveInstances,nrOfCompletedInstances);
			}
			executionEntity.setVariables(lcReceiveNParam.getVariables());// 设置流程变量
			taskService.complete(lcReceiveNParam.getTaskId());
			return new LcMutilEntity();
		}
	}

	/**
	 *  根据BPM+节点id判断节点是否为结束节点
	 * 该方法无需流程部署
	 * @param bpmn
	 * @return
	 */
	public Boolean validateEnd(String bpmn,String activityId){
		if(StringUtil.isEmpty(bpmn)){
			throw new ExceptionUtil("未能获取到bpmn字符串");
		}
		if(StringUtil.isEmpty(activityId)){
			throw new ExceptionUtil("未能获取到节点id");
		}
		InputStream resouceStream = new ByteArrayInputStream(bpmn.getBytes(StandardCharsets.UTF_8));
		XMLInputFactory xif = XMLInputFactory.newInstance();
		InputStreamReader in;
		XMLStreamReader xtr;
		try {
			in = new InputStreamReader(resouceStream, "UTF-8");
			xtr = xif.createXMLStreamReader(in);
			BpmnModel model = new BpmnXMLConverter().convertToBpmnModel(xtr);
			List<EndEvent> endEvents  = model.getMainProcess().findFlowElementsOfType(EndEvent.class);
			if(CollectionUtil.isEmpty(endEvents)){
				return false;
			}
			for(EndEvent endEvent:endEvents){
				if(activityId.equals(endEvent.getId())){
					return true;
				}
			}
		} catch (XMLStreamException e) {
			log.error("验证是否结束节点XMLStreamException异常：{}",e);
		} catch (UnsupportedEncodingException e) {
			log.error("验证是否结束节点UnsupportedEncodingException异常：{}",e);
		}
		return false;
	}

	/**
	 * 查询指定节点已审批的人
	 * @param lcReceiveNParam
	 */
	public BaseResult getNodeUser(LcReceiveNParam lcReceiveNParam){
		BaseResult baseResult = new BaseResult();
		if(null == lcReceiveNParam){
			throw new ExceptionUtil("查询指定节点已审批的人时，lcReceiveNParam为空！");
		}
		if(StringUtil.isEmpty(lcReceiveNParam.getProcessInstanceId())){
			throw new ExceptionUtil("查询指定节点已审批的人时，流程实例id为空！");
		}
		List<HistoricTaskInstance> historicTaskInstanceList = historyService.createHistoricTaskInstanceQuery().processInstanceId(lcReceiveNParam.getProcessInstanceId()).taskDefinitionKey(lcReceiveNParam.getActivityId()).orderByTaskCreateTime().desc().list();//根据对象获取流程定义Id
		if(!CollectionUtil.isEmpty(historicTaskInstanceList)){
			baseResult.setData(historicTaskInstanceList.get(0).getAssignee());
		}
		return baseResult;
	}
}
